diff options
Diffstat (limited to 'flang/lib/Parser/prescan.cpp')
| -rw-r--r-- | flang/lib/Parser/prescan.cpp | 75 |
1 files changed, 46 insertions, 29 deletions
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp index df0372b..4739da0 100644 --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -1380,19 +1380,23 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) { } } } else { // Normal case: not in a compiler directive. - // !$ conditional compilation lines may be continuations when not + // Conditional compilation lines may be continuations when not // just preprocessing. - if (!preprocessingOnly_ && IsFixedFormCommentChar(col1) && - nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' && - nextLine_[4] == ' ' && IsCompilerDirectiveSentinel(&nextLine_[1], 1)) { - if (const char *col6{nextLine_ + 5}; - *col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) { - if (atNewline && !IsSpace(nextLine_ + 6)) { - brokenToken_ = true; + if (!preprocessingOnly_ && IsFixedFormCommentChar(col1)) { + if ((nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' && + nextLine_[4] == ' ' && + IsCompilerDirectiveSentinel(&nextLine_[1], 1)) || + (nextLine_[1] == '@' && + IsCompilerDirectiveSentinel(&nextLine_[1], 4))) { + if (const char *col6{nextLine_ + 5}; + *col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) { + if (atNewline && !IsSpace(nextLine_ + 6)) { + brokenToken_ = true; + } + return nextLine_ + 6; + } else { + return nullptr; } - return nextLine_ + 6; - } else { - return nullptr; } } if (col1 == '&' && @@ -1427,6 +1431,15 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) { return nullptr; // not a continuation line } +constexpr bool IsDirective(const char *match, const char *dir) { + for (; *match; ++match) { + if (*match != ToLowerCaseLetter(*dir++)) { + return false; + } + } + return true; +} + const char *Prescanner::FreeFormContinuationLine(bool ampersand) { const char *lineStart{nextLine_}; const char *p{lineStart}; @@ -1439,12 +1452,18 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) { if (preprocessingOnly_) { // in -E mode, don't treat !$ as a continuation return nullptr; - } else if (p[0] == '!' && p[1] == '$') { - // accept but do not require a matching sentinel - if (p[2] != '&' && !IsSpaceOrTab(&p[2])) { - return nullptr; // not !$ - } + } else if (p[0] == '!' && (p[1] == '$' || p[1] == '@')) { p += 2; + if (InOpenACCOrCUDAConditionalLine()) { + if (IsDirective("acc", p) || IsDirective("cuf", p)) { + p += 3; + } else { + return nullptr; + } + } + if (*p != '&' && !IsSpaceOrTab(p)) { + return nullptr; + } } } else if (*p++ == '!') { for (const char *s{directiveSentinel_}; *s != '\0'; ++p, ++s) { @@ -1467,10 +1486,17 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) { return nullptr; } } - if (p[0] == '!' && p[1] == '$' && !preprocessingOnly_ && - features_.IsEnabled(LanguageFeature::OpenMP)) { - // !$ conditional line can be a continuation - p = lineStart = SkipWhiteSpace(p + 2); + if (p[0] == '!' && !preprocessingOnly_) { + // Conditional lines can be continuations + if (p[1] == '$' && features_.IsEnabled(LanguageFeature::OpenMP)) { + p = lineStart = SkipWhiteSpace(p + 2); + } else if (IsDirective("@acc", p + 1) && + features_.IsEnabled(LanguageFeature::OpenACC)) { + p = lineStart = SkipWhiteSpace(p + 5); + } else if (IsDirective("@cuf", p + 1) && + features_.IsEnabled(LanguageFeature::CUDA)) { + p = lineStart = SkipWhiteSpace(p + 5); + } } if (*p == '&') { return p + 1; @@ -1706,15 +1732,6 @@ Prescanner::IsCompilerDirectiveSentinel(const char *p) const { return std::nullopt; } -constexpr bool IsDirective(const char *match, const char *dir) { - for (; *match; ++match) { - if (*match != ToLowerCaseLetter(*dir++)) { - return false; - } - } - return true; -} - Prescanner::LineClassification Prescanner::ClassifyLine( const char *start) const { if (inFixedForm_) { |
