[m-rev.] for review: generate error messages for invalid grade component combinations

Julien Fischer jfischer at opturion.com
Fri Apr 17 14:34:30 AEST 2015


For review by anyone.

--------------

Generate error messages for invalid grade component combinations.

compiler/handle_options.m:
 	Generate (better) error messages for invalid combinations of grade
 	components.

diff --git a/compiler/handle_options.m b/compiler/handle_options.m
index 47ffbe1..efe25ab 100644
--- a/compiler/handle_options.m
+++ b/compiler/handle_options.m
@@ -692,6 +692,12 @@ convert_options_to_globals(OptionTable0, Target, GC_Method, TagsMethod0,
          HostEnvType, SystemEnvType, TargetEnvType, FileInstallCmd,
          LimitErrorContextsMap, !:Globals),

+    % NOTE: this call must occur *before* any code below that implicitly
+    % sets options based on the target language or GC method.
+    %
+    check_grade_component_compatibility(!.Globals, Target, GC_Method,
+        !Errors),
+
      globals.lookup_string_option(!.Globals, event_set_file_name,
          EventSetFileName0),
      ( EventSetFileName0 = "" ->
@@ -2547,6 +2553,193 @@ disable_smart_recompilation(OptionDescr, !Globals, !IO) :-
          WarnSmart = no
      ).

+%-----------------------------------------------------------------------------%
+
+    % This predicate generates error messages for various combinations of
+    % grade components (or their equivalent command line options) that are
+    % incompatible with each other.
+    %
+    % NOTE this predicate does not check *all* combinations, some of the checks
+    % are carried out by the predicate convert_options_to_globals, while others
+    % are carried out by the code that decomposes the grade string.
+    %
+    % NOTE: since grade components may be specified by either a grade component
+    % or via a command line option, please try to ensure that the error
+    % messages generated by this predicate cover both situations.
+    %
+    % XXX we don't currently handle the .par, .threadscope or any undocumented
+    % grade components here.
+    %
+:- pred check_grade_component_compatibility(globals::in,
+    compilation_target::in, gc_method::in,
+    cord(string)::in, cord(string)::out) is det.
+
+check_grade_component_compatibility(Globals, Target, GC_Method, !Errors) :-
+    TargetStr = compilation_target_string(Target),
+
+    % Check that the GC method is compatible with the target language.
+    %
+    (
+        Target = target_c
+        % XXX how are we supposed to handle gc_automatic for C?
+    ;
+        ( Target = target_csharp
+        ; Target = target_erlang
+        ; Target = target_il
+        ; Target = target_java
+        ),
+        (
+            % At this point, both of these values are acceptable for the
+            % non-C targets.
+            ( GC_Method = gc_automatic
+            ; GC_Method = gc_none
+            )
+        ;
+            ( GC_Method = gc_boehm
+            ; GC_Method = gc_boehm_debug
+            ),
+            string.format(
+                "use of the Boehm GC is incompatible with target language %s",
+                [s(TargetStr)], BoehmIncompatibleMsg),
+            add_error(BoehmIncompatibleMsg, !Errors)
+        ;
+            GC_Method = gc_hgc,
+            string.format(
+                "use of HGC is incompatible with target language %s",
+                [s(TargetStr)], HGC_IncompatibleMsg),
+            add_error(HGC_IncompatibleMsg, !Errors)
+        ;
+            GC_Method = gc_accurate,
+            string.format(
+                "use of the accurate GC is incompatible with target language %s",
+                [s(TargetStr)],  AGC_IncompatibleMsg),
+            add_error(AGC_IncompatibleMsg, !Errors)
+        )
+    ),
+
+    % Time profiling is only supported by the C back-ends.
+    %
+    globals.lookup_bool_option(Globals, profile_time, ProfileTime),
+    (
+        ProfileTime = yes,
+        (
+            ( Target = target_java
+            ; Target = target_il
+            ; Target = target_csharp
+            ; Target = target_erlang
+            ),
+            add_error("time profiling is incompatible with target language " ++
+                TargetStr, !Errors)
+        ;
+            Target = target_c
+        )
+    ;
+        ProfileTime = no
+    ),
+
+    % Memory profiling is only supported by the C back-ends.
+    %
+    globals.lookup_bool_option(Globals, profile_memory, ProfileMemory),
+    (
+        ProfileMemory = yes,
+        (
+            ( Target = target_java
+            ; Target = target_il
+            ; Target = target_csharp
+            ; Target = target_erlang
+            ),
+            add_error("memory profiling is incompatible with target language " ++
+                TargetStr, !Errors)
+        ;
+            Target = target_c
+        )
+    ;
+        ProfileMemory = no
+    ),
+
+    % NOTE: compatibility with profile_deep is checked elsewhere.
+
+    % NOTE: compatibility with debugging is checked elsewhere.
+
+    % Trailing is only supported by the C back-ends.
+    %
+    globals.lookup_bool_option(Globals, use_trail,  UseTrail),
+    globals.lookup_bool_option(Globals, trail_segments, TrailSegments),
+    (
+        % NOTE: We haven't yet implicitly enabled use_trail segments
+        % if trail_segments are enabled, so we must check both here.
+        ( UseTrail = yes
+        ; TrailSegments = yes
+        )
+    ->
+        (
+            ( Target = target_java
+            ; Target = target_il
+            ; Target = target_csharp
+            ; Target = target_erlang
+            ),
+            add_error("trailing is incompatible with target language " ++
+                TargetStr, !Errors)
+        ;
+            Target = target_c
+        )
+    ;
+        true
+    ),
+
+    % Stack segments are only supported by the low level C back-end.
+    %
+    globals.lookup_bool_option(Globals, stack_segments, StackSegments),
+    (
+        StackSegments = yes,
+        (
+            Target = target_c,
+            globals.lookup_bool_option(Globals, highlevel_code, HighLevelCode),
+            (
+                HighLevelCode = yes,
+                add_error(
+                "stack segments are incompatible with the high-level C backend",
+                !Errors)
+            ;
+                HighLevelCode = no
+            )
+        ;
+            ( Target = target_java
+            ; Target = target_il
+            ; Target = target_csharp
+            ; Target = target_erlang
+            ),
+            add_error("stack segments are incompatible with target language " ++
+                TargetStr, !Errors)
+        )
+    ;
+        StackSegments = no
+    ),
+
+    % Single precision floats are only compatible with the C back-ends.
+    % (At least for Mercury, that's currently the case.)
+    globals.lookup_bool_option(Globals, single_prec_float, SinglePrecFloat),
+    (
+        SinglePrecFloat = yes,
+        (
+            ( Target = target_java
+            ; Target = target_il
+            ; Target = target_csharp
+            ; Target = target_erlang
+            ),
+            string.format(
+                "single precision floats are incompatible with target language %s",
+                [s(TargetStr)], SinglePrecFloatMsg),
+            add_error(SinglePrecFloatMsg, !Errors)
+        ;
+            Target = target_c
+        )
+    ;
+        SinglePrecFloat = no
+    ).
+
+%-----------------------------------------------------------------------------%
+
  usage_errors(Errors, !IO) :-
      io.progname_base("mercury_compile", ProgName, !IO),
      list.foldl(write_error_plain_with_progname(ProgName), Errors, !IO),



More information about the reviews mailing list