Browse Source

+ support $lgeacyifend directive, resolves #37676

florian 3 years ago
parent
commit
dcb1fcd9b8

+ 2 - 1
compiler/globtype.pas

@@ -171,7 +171,8 @@ interface
          { i8086 specific }
          { i8086 specific }
          cs_force_far_calls,
          cs_force_far_calls,
          cs_hugeptr_arithmetic_normalization,
          cs_hugeptr_arithmetic_normalization,
-         cs_hugeptr_comparison_normalization
+         cs_hugeptr_comparison_normalization,
+         cs_legacyifend
        );
        );
        tlocalswitches = set of tlocalswitch;
        tlocalswitches = set of tlocalswitch;
 
 

+ 9 - 1
compiler/msg/errore.msg

@@ -146,7 +146,7 @@ general_t_unitscope=01027_T_Using unit scope: $1
 #
 #
 # Scanner
 # Scanner
 #
 #
-# 02105 is the last used one
+# 02107 is the last used one
 #
 #
 % \section{Scanner messages.}
 % \section{Scanner messages.}
 % This section lists the messages that the scanner emits. The scanner takes
 % This section lists the messages that the scanner emits. The scanner takes
@@ -433,6 +433,14 @@ scan_w_setpesubsysversion_not_support=02104_W_SETPESUBSYSVERSION is not supporte
 % The \var{\{\$SETPESUBSYSVERSION\}} directive is not supported by the target OS.
 % The \var{\{\$SETPESUBSYSVERSION\}} directive is not supported by the target OS.
 scan_n_changecputype=02105_N_Changed CPU type to be consistent with specified controller
 scan_n_changecputype=02105_N_Changed CPU type to be consistent with specified controller
 scan_e_emptymacroname=02106_E_A macro/compiler variable name cannot be empty
 scan_e_emptymacroname=02106_E_A macro/compiler variable name cannot be empty
+scan_e_unexpected_ifend=02107_E_$IFEND directive found without a matching $IF directive
+% When legacy ifend is turned on by the directive \var{\$LEGACYIFEND}, then the
+% \var{\$IF} directive must be closed by the \var{\$IFEND} directive and the
+% \var{\$IFDEF} directive must be closed by the \var{\$ENDIF} directive.
+scan_e_unexpected_endif=02108_E_$ENDIF directive found without a matching $IF(N)DEF directive
+% When legacy ifend is turned on by the directive \var{\$LEGACYIFEND}, then the
+% \var{\$IF} directive must be closed by the \var{\$IFEND} directive and the
+% \var{\$IFDEF} directive must be closed by the \var{\$ENDIF} directive.
 % \end{description}
 % \end{description}
 #
 #
 # Parser
 # Parser

+ 4 - 2
compiler/msgidx.inc

@@ -130,6 +130,8 @@ const
   scan_w_setpesubsysversion_not_support=02104;
   scan_w_setpesubsysversion_not_support=02104;
   scan_n_changecputype=02105;
   scan_n_changecputype=02105;
   scan_e_emptymacroname=02106;
   scan_e_emptymacroname=02106;
+  scan_e_unexpected_ifend=02107;
+  scan_e_unexpected_endif=02108;
   parser_e_syntax_error=03000;
   parser_e_syntax_error=03000;
   parser_e_dont_nest_interrupt=03004;
   parser_e_dont_nest_interrupt=03004;
   parser_w_proc_directive_ignored=03005;
   parser_w_proc_directive_ignored=03005;
@@ -1143,9 +1145,9 @@ const
   option_info=11024;
   option_info=11024;
   option_help_pages=11025;
   option_help_pages=11025;
 
 
-  MsgTxtSize = 88697;
+  MsgTxtSize = 88831;
 
 
   MsgIdxMax : array[1..20] of longint=(
   MsgIdxMax : array[1..20] of longint=(
-    28,107,361,131,99,63,147,37,223,69,
+    28,109,361,131,99,63,147,37,223,69,
     65,20,30,1,1,1,1,1,1,1
     65,20,30,1,1,1,1,1,1,1
   );
   );

File diff suppressed because it is too large
+ 644 - 641
compiler/msgtxt.inc


+ 5 - 0
compiler/scandir.pas

@@ -1033,6 +1033,10 @@ unit scandir;
           end;
           end;
       end;
       end;
 
 
+    procedure dir_legacyifend;
+      begin
+        do_localswitch(cs_legacyifend);
+      end;
 
 
     procedure dir_mmx;
     procedure dir_mmx;
       begin
       begin
@@ -1990,6 +1994,7 @@ unit scandir;
         AddDirective('INLINE',directive_all, @dir_inline);
         AddDirective('INLINE',directive_all, @dir_inline);
         AddDirective('INTERFACES',directive_all, @dir_interfaces);
         AddDirective('INTERFACES',directive_all, @dir_interfaces);
         AddDirective('L',directive_all, @dir_link);
         AddDirective('L',directive_all, @dir_link);
+        AddDirective('LEGACYIFEND',directive_all, @dir_legacyifend);
         AddDirective('LIBEXPORT',directive_mac, @dir_libexport);
         AddDirective('LIBEXPORT',directive_mac, @dir_libexport);
         AddDirective('LIBRARYPATH',directive_all, @dir_librarypath);
         AddDirective('LIBRARYPATH',directive_all, @dir_librarypath);
         AddDirective('LINK',directive_all, @dir_link);
         AddDirective('LINK',directive_all, @dir_link);

+ 19 - 3
compiler/scanner.pas

@@ -46,7 +46,10 @@ interface
        preproctyp = (pp_ifdef,pp_ifndef,pp_if,pp_ifopt,pp_else,pp_elseif);
        preproctyp = (pp_ifdef,pp_ifndef,pp_if,pp_ifopt,pp_else,pp_elseif);
 
 
        tpreprocstack = class
        tpreprocstack = class
-          typ     : preproctyp;
+          typ,
+          { stores the preproctyp of the last (else)if(ndef) directive
+            so we can check properly for ifend when legacyifend is on }
+          iftyp   : preproctyp;
           accept  : boolean;
           accept  : boolean;
           next    : tpreprocstack;
           next    : tpreprocstack;
           name    : TIDString;
           name    : TIDString;
@@ -783,9 +786,21 @@ implementation
         current_scanner.elsepreprocstack;
         current_scanner.elsepreprocstack;
       end;
       end;
 
 
-
     procedure dir_endif;
     procedure dir_endif;
       begin
       begin
+        if (cs_legacyifend in current_settings.localswitches) and
+          (current_scanner.preprocstack.typ<>pp_ifdef) and (current_scanner.preprocstack.typ<>pp_ifndef) and
+            not((current_scanner.preprocstack.typ=pp_else) and (current_scanner.preprocstack.iftyp in [pp_ifdef,pp_ifndef])) then
+          Message(scan_e_unexpected_endif);
+        current_scanner.poppreprocstack;
+      end;
+
+    procedure dir_ifend;
+      begin
+        if (cs_legacyifend in current_settings.localswitches) and
+          (current_scanner.preprocstack.typ<>pp_elseif) and (current_scanner.preprocstack.typ<>pp_if) and
+            not((current_scanner.preprocstack.typ=pp_else) and (current_scanner.preprocstack.iftyp in [pp_if,pp_elseif])) then
+          Message(scan_e_unexpected_ifend);
         current_scanner.poppreprocstack;
         current_scanner.poppreprocstack;
       end;
       end;
 
 
@@ -3906,6 +3921,7 @@ type
            else
            else
              if (not(assigned(preprocstack.next)) or (preprocstack.next.accept)) then
              if (not(assigned(preprocstack.next)) or (preprocstack.next.accept)) then
                preprocstack.accept:=not preprocstack.accept;
                preprocstack.accept:=not preprocstack.accept;
+           preprocstack.iftyp:=preprocstack.typ;
            preprocstack.typ:=pp_else;
            preprocstack.typ:=pp_else;
            preprocstack.line_nb:=line_no;
            preprocstack.line_nb:=line_no;
            preprocstack.fileindex:=current_filepos.fileindex;
            preprocstack.fileindex:=current_filepos.fileindex;
@@ -5862,7 +5878,7 @@ exit_label:
         AddDirective('LIBSUFFIX',directive_turbo, @dir_libsuffix);
         AddDirective('LIBSUFFIX',directive_turbo, @dir_libsuffix);
         AddDirective('EXTENSION',directive_turbo, @dir_extension);
         AddDirective('EXTENSION',directive_turbo, @dir_extension);
 
 
-        AddConditional('IFEND',directive_turbo, @dir_endif);
+        AddConditional('IFEND',directive_turbo, @dir_ifend);
         AddConditional('IFOPT',directive_turbo, @dir_ifopt);
         AddConditional('IFOPT',directive_turbo, @dir_ifopt);
 
 
         { Directives and conditionals for mode macpas: }
         { Directives and conditionals for mode macpas: }

+ 2 - 1
compiler/utils/ppuutils/ppudump.pp

@@ -2371,7 +2371,8 @@ const
          { i8086 specific }
          { i8086 specific }
         'i8086 force FAR calls', {cs_force_far_calls}
         'i8086 force FAR calls', {cs_force_far_calls}
         'i8086 huge pointer arithmetic', {cs_hugeptr_arithmetic_normalization}
         'i8086 huge pointer arithmetic', {cs_hugeptr_arithmetic_normalization}
-        'i8086 huge pointer comparison' {cs_hugeptr_comparison_normalization}
+        'i8086 huge pointer comparison', {cs_hugeptr_comparison_normalization}
+        'enforce legacy ifend behaviour' {cs_legacyifend}
        );
        );
        { Switches which can be changed by a mode (fpc,tp7,delphi) }
        { Switches which can be changed by a mode (fpc,tp7,delphi) }
        modeswitchname : array[tmodeswitch] of string[50] =
        modeswitchname : array[tmodeswitch] of string[50] =

+ 9 - 0
tests/tbf/tb0277.pp

@@ -0,0 +1,9 @@
+{ %fail }
+{$legacyifend on}
+
+program test;
+{$if defined(asdf)}
+{$endif}
+
+begin
+end.

+ 9 - 0
tests/tbf/tb0278.pp

@@ -0,0 +1,9 @@
+{ %fail }
+{$legacyifend on}
+
+program test;
+{$ifdef asdf}
+{$ifend}
+
+begin
+end.

+ 10 - 0
tests/tbf/tb0279.pp

@@ -0,0 +1,10 @@
+{ %fail }
+{$legacyifend on}
+
+program test;
+{$if defined(asdf)}
+{$else}
+{$endif}
+
+begin
+end.

+ 10 - 0
tests/tbf/tb0280.pp

@@ -0,0 +1,10 @@
+{ %fail }
+{$legacyifend on}
+
+program test;
+{$ifdef asdf}
+{$else}
+{$ifend}
+
+begin
+end.

Some files were not shown because too many files changed in this diff