diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h --- a/flang/lib/Parser/prescan.h +++ b/flang/lib/Parser/prescan.h @@ -166,6 +166,7 @@ const char *IsPreprocessorDirectiveLine(const char *) const; const char *FixedFormContinuationLine(bool mightNeedSpace); const char *FreeFormContinuationLine(bool ampersand); + bool IsImplicitContinuation() const; bool FixedFormContinuation(bool mightNeedSpace); bool FreeFormContinuation(); bool Continuation(bool mightNeedFixedFormSpace); diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -887,10 +887,8 @@ return nextLine_ + 6; } } - if (delimiterNesting_ > 0) { - if (!IsFixedFormCommentChar(col1)) { - return nextLine_; - } + if (IsImplicitContinuation()) { + return nextLine_; } } return nullptr; // not a continuation line @@ -927,7 +925,7 @@ return p + 1; } else if (*p == '!' || *p == '\n' || *p == '#') { return nullptr; - } else if (ampersand || delimiterNesting_ > 0) { + } else if (ampersand || IsImplicitContinuation()) { if (p > nextLine_) { --p; } else { @@ -981,6 +979,14 @@ return false; } +// Implicit line continuation allows a preprocessor macro call with +// arguments to span multiple lines. +bool Prescanner::IsImplicitContinuation() const { + return !inPreprocessorDirective_ && !inCharLiteral_ && + delimiterNesting_ > 0 && nextLine_ < limit_ && + ClassifyLine(nextLine_).kind == LineClassification::Kind::Source; +} + bool Prescanner::Continuation(bool mightNeedFixedFormSpace) { if (*at_ == '\n' || *at_ == '&') { if (inFixedForm_) { diff --git a/flang/test/Parser/continuation-in-if.f b/flang/test/Parser/continuation-in-if.f new file mode 100644 --- /dev/null +++ b/flang/test/Parser/continuation-in-if.f @@ -0,0 +1,9 @@ +! RUN: %f18 -funparse %s 2>&1 | FileCheck %s +! CHECK: CALL foo("N","N") +#ifdef transpose + call foo('T', +#else + call foo('N', +#endif + $ 'N') + end