@@ -105,13 +105,15 @@ void Prescanner::Statement() {
105
105
NextLine ();
106
106
return ;
107
107
case LineClassification::Kind::ConditionalCompilationDirective:
108
- case LineClassification::Kind::DefinitionDirective:
109
- case LineClassification::Kind::PreprocessorDirective:
108
+ case LineClassification::Kind::IncludeDirective:
110
109
preprocessor_.Directive (TokenizePreprocessorDirective (), *this );
110
+ afterPreprocessingDirective_ = true ;
111
+ skipLeadingAmpersand_ |= !inFixedForm_;
111
112
return ;
112
- case LineClassification::Kind::IncludeDirective:
113
+ case LineClassification::Kind::PreprocessorDirective:
114
+ case LineClassification::Kind::DefinitionDirective:
113
115
preprocessor_.Directive (TokenizePreprocessorDirective (), *this );
114
- afterIncludeDirective_ = true ;
116
+ // Don't set afterPreprocessingDirective_
115
117
return ;
116
118
case LineClassification::Kind::CompilerDirective: {
117
119
directiveSentinel_ = line.sentinel ;
@@ -171,15 +173,17 @@ void Prescanner::Statement() {
171
173
NextChar ();
172
174
}
173
175
LabelField (tokens);
174
- } else if (skipLeadingAmpersand_) {
175
- skipLeadingAmpersand_ = false ;
176
- const char *p{SkipWhiteSpace (at_)};
177
- if (p < limit_ && *p == ' &' ) {
178
- column_ += ++p - at_;
179
- at_ = p;
180
- }
181
176
} else {
182
- SkipSpaces ();
177
+ if (skipLeadingAmpersand_) {
178
+ skipLeadingAmpersand_ = false ;
179
+ const char *p{SkipWhiteSpace (at_)};
180
+ if (p < limit_ && *p == ' &' ) {
181
+ column_ += ++p - at_;
182
+ at_ = p;
183
+ }
184
+ } else {
185
+ SkipSpaces ();
186
+ }
183
187
// Check for a leading identifier that might be a keyword macro
184
188
// that will expand to anything indicating a non-source line, like
185
189
// a comment marker or directive sentinel. If so, disable line
@@ -289,13 +293,14 @@ void Prescanner::CheckAndEmitLine(
289
293
tokens.CheckBadFortranCharacters (
290
294
messages_, *this , disableSourceContinuation_);
291
295
// Parenthesis nesting check does not apply while any #include is
292
- // active, nor on the lines before and after a top-level #include.
296
+ // active, nor on the lines before and after a top-level #include,
297
+ // nor before or after conditional source.
293
298
// Applications play shenanigans with line continuation before and
294
- // after #include'd subprogram argument lists.
299
+ // after #include'd subprogram argument lists and conditional source .
295
300
if (!isNestedInIncludeDirective_ && !omitNewline_ &&
296
- !afterIncludeDirective_ && tokens.BadlyNestedParentheses ()) {
297
- if (inFixedForm_ && nextLine_ < limit_ &&
298
- IsPreprocessorDirectiveLine (nextLine_)) {
301
+ !afterPreprocessingDirective_ && tokens.BadlyNestedParentheses () &&
302
+ !preprocessor_. InConditional ()) {
303
+ if (nextLine_ < limit_ && IsPreprocessorDirectiveLine (nextLine_)) {
299
304
// don't complain
300
305
} else {
301
306
tokens.CheckBadParentheses (messages_);
@@ -306,7 +311,7 @@ void Prescanner::CheckAndEmitLine(
306
311
omitNewline_ = false ;
307
312
} else {
308
313
cooked_.Put (' \n ' , newlineProvenance);
309
- afterIncludeDirective_ = false ;
314
+ afterPreprocessingDirective_ = false ;
310
315
}
311
316
}
312
317
@@ -353,10 +358,11 @@ void Prescanner::LabelField(TokenSequence &token) {
353
358
++column_;
354
359
}
355
360
if (badColumn && !preprocessor_.IsNameDefined (token.CurrentOpenToken ())) {
356
- if (prescannerNesting_ > 0 && *badColumn == 6 &&
357
- cooked_.BufferedBytes () == firstCookedCharacterOffset_) {
358
- // This is the first source line in #included text or conditional
359
- // code under #if.
361
+ if ((prescannerNesting_ > 0 && *badColumn == 6 &&
362
+ cooked_.BufferedBytes () == firstCookedCharacterOffset_) ||
363
+ afterPreprocessingDirective_) {
364
+ // This is the first source line in #include'd text or conditional
365
+ // code under #if, or the first source line after such.
360
366
// If it turns out that the preprocessed text begins with a
361
367
// fixed form continuation line, the newline at the end
362
368
// of the latest source line beforehand will be deleted in
@@ -599,7 +605,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
599
605
char previous{at_ <= start_ ? ' ' : at_[-1 ]};
600
606
NextChar ();
601
607
SkipSpaces ();
602
- if (*at_ == ' \n ' ) {
608
+ if (*at_ == ' \n ' && !omitNewline_ ) {
603
609
// Discard white space at the end of a line.
604
610
} else if (!inPreprocessorDirective_ &&
605
611
(previous == ' (' || *at_ == ' (' || *at_ == ' )' )) {
@@ -1069,6 +1075,17 @@ bool Prescanner::SkipCommentLine(bool afterAmpersand) {
1069
1075
return true ;
1070
1076
} else if (inPreprocessorDirective_) {
1071
1077
return false ;
1078
+ } else if (afterAmpersand &&
1079
+ (lineClass.kind ==
1080
+ LineClassification::Kind::ConditionalCompilationDirective ||
1081
+ lineClass.kind == LineClassification::Kind::DefinitionDirective ||
1082
+ lineClass.kind == LineClassification::Kind::PreprocessorDirective ||
1083
+ lineClass.kind == LineClassification::Kind::IncludeDirective ||
1084
+ lineClass.kind == LineClassification::Kind::IncludeLine)) {
1085
+ SkipToEndOfLine ();
1086
+ omitNewline_ = true ;
1087
+ skipLeadingAmpersand_ = true ;
1088
+ return false ;
1072
1089
} else if (lineClass.kind ==
1073
1090
LineClassification::Kind::ConditionalCompilationDirective ||
1074
1091
lineClass.kind == LineClassification::Kind::PreprocessorDirective) {
@@ -1080,13 +1097,6 @@ bool Prescanner::SkipCommentLine(bool afterAmpersand) {
1080
1097
// continued line).
1081
1098
preprocessor_.Directive (TokenizePreprocessorDirective (), *this );
1082
1099
return true ;
1083
- } else if (afterAmpersand &&
1084
- (lineClass.kind == LineClassification::Kind::IncludeDirective ||
1085
- lineClass.kind == LineClassification::Kind::IncludeLine)) {
1086
- SkipToEndOfLine ();
1087
- omitNewline_ = true ;
1088
- skipLeadingAmpersand_ = true ;
1089
- return false ;
1090
1100
} else {
1091
1101
return false ;
1092
1102
}
0 commit comments