diff options
Diffstat (limited to 'flang/lib/Parser')
| -rw-r--r-- | flang/lib/Parser/openmp-parsers.cpp | 12 | ||||
| -rw-r--r-- | flang/lib/Parser/prescan.cpp | 75 | ||||
| -rw-r--r-- | flang/lib/Parser/program-parsers.cpp | 2 | ||||
| -rw-r--r-- | flang/lib/Parser/unparse.cpp | 4 |
4 files changed, 55 insertions, 38 deletions
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index c0472ad..d1e081c 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -367,8 +367,8 @@ struct OmpArgumentListParser { }; TYPE_PARSER( // - construct<OmpTypeSpecifier>(Parser<DeclarationTypeSpec>{}) || - construct<OmpTypeSpecifier>(Parser<TypeSpec>{})) + construct<OmpTypeName>(Parser<DeclarationTypeSpec>{}) || + construct<OmpTypeName>(Parser<TypeSpec>{})) // 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list) TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) || @@ -376,8 +376,8 @@ TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) || TYPE_PARSER(construct<OmpReductionSpecifier>( // Parser<OmpReductionIdentifier>{}, - ":"_tok >> nonemptyList(Parser<OmpTypeSpecifier>{}), - maybe(":"_tok >> Parser<OmpReductionCombiner>{}))) + ":"_tok >> nonemptyList(Parser<OmpTypeName>{}), + maybe(":"_tok >> Parser<OmpCombinerExpression>{}))) // --- Parsers for context traits ------------------------------------- @@ -1832,8 +1832,8 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareMapperConstruct>( IsDirective(llvm::omp::Directive::OMPD_declare_mapper)) >= Parser<OmpDirectiveSpecification>{}))) -TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) || - construct<OmpReductionCombiner>(Parser<FunctionReference>{})) +TYPE_PARSER(construct<OmpCombinerExpression>(Parser<AssignmentStmt>{}) || + construct<OmpCombinerExpression>(Parser<FunctionReference>{})) TYPE_PARSER(sourced(construct<OpenMPCriticalConstruct>( OmpBlockConstructParser{llvm::omp::Directive::OMPD_critical}))) 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_) { diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp index 92c0a64..740dbbf 100644 --- a/flang/lib/Parser/program-parsers.cpp +++ b/flang/lib/Parser/program-parsers.cpp @@ -484,7 +484,7 @@ constexpr auto starOrExpr{ applyFunction(presentOptional<ScalarExpr>, scalarExpr))}; TYPE_PARSER(extension<LanguageFeature::CUDA>( "<<<" >> construct<CallStmt::Chevrons>(starOrExpr, ", " >> scalarExpr, - maybe("," >> scalarIntExpr), maybe("," >> scalarIntExpr)) / + maybe("," >> scalarExpr), maybe("," >> scalarIntExpr)) / ">>>")) constexpr auto actualArgSpecList{optionalList(actualArgSpec)}; TYPE_CONTEXT_PARSER("CALL statement"_en_US, diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index b172e429..2f86c76 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2111,7 +2111,7 @@ public: Walk(std::get<OmpReductionIdentifier>(x.t)); Put(":"); Walk(std::get<OmpTypeNameList>(x.t)); - Walk(": ", std::get<std::optional<OmpReductionCombiner>>(x.t)); + Walk(": ", std::get<std::optional<OmpCombinerExpression>>(x.t)); } void Unparse(const llvm::omp::Directive &x) { unsigned ompVersion{langOpts_.OpenMPVersion}; @@ -2519,7 +2519,7 @@ public: Walk(x.u); } } - void Unparse(const OmpReductionCombiner &x) { + void Unparse(const OmpCombinerExpression &x) { // Don't let the visitor go to the normal AssignmentStmt Unparse function, // it adds an extra newline that we don't want. if (const auto *assignment{std::get_if<AssignmentStmt>(&x.u)}) { |
