aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Parser
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Parser')
-rw-r--r--flang/lib/Parser/openmp-parsers.cpp12
-rw-r--r--flang/lib/Parser/prescan.cpp75
-rw-r--r--flang/lib/Parser/program-parsers.cpp2
-rw-r--r--flang/lib/Parser/unparse.cpp4
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)}) {