aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Semantics')
-rw-r--r--flang/lib/Semantics/resolve-directives.cpp17
-rw-r--r--flang/lib/Semantics/resolve-names.cpp99
2 files changed, 56 insertions, 60 deletions
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 196755e..628068f 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -26,6 +26,8 @@
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
#include "flang/Support/Flags.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMP.h.inc"
#include "llvm/Support/Debug.h"
#include <list>
@@ -453,6 +455,21 @@ public:
return true;
}
+ bool Pre(const parser::OmpStylizedDeclaration &x) {
+ static llvm::StringMap<Symbol::Flag> map{
+ {"omp_in", Symbol::Flag::OmpInVar},
+ {"omp_orig", Symbol::Flag::OmpOrigVar},
+ {"omp_out", Symbol::Flag::OmpOutVar},
+ {"omp_priv", Symbol::Flag::OmpPrivVar},
+ };
+ if (auto &name{std::get<parser::ObjectName>(x.var.t)}; name.symbol) {
+ if (auto found{map.find(name.ToString())}; found != map.end()) {
+ ResolveOmp(name, found->second,
+ const_cast<Scope &>(DEREF(name.symbol).owner()));
+ }
+ }
+ return false;
+ }
bool Pre(const parser::OmpMetadirectiveDirective &x) {
PushContext(x.v.source, llvm::omp::Directive::OMPD_metadirective);
return true;
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 93faba7..0e6d4c7 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1605,6 +1605,12 @@ public:
Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
+ void Post(const parser::OmpTypeName &);
+ bool Pre(const parser::OmpStylizedDeclaration &);
+ void Post(const parser::OmpStylizedDeclaration &);
+ bool Pre(const parser::OmpStylizedInstance &);
+ void Post(const parser::OmpStylizedInstance &);
+
bool Pre(const parser::OpenMPDeclareMapperConstruct &x) {
AddOmpSourceRange(x.source);
return true;
@@ -1615,18 +1621,6 @@ public:
return true;
}
- bool Pre(const parser::OmpInitializerProc &x) {
- auto &procDes = std::get<parser::ProcedureDesignator>(x.t);
- auto &name = std::get<parser::Name>(procDes.u);
- auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
- if (!symbol) {
- context().Say(name.source,
- "Implicit subroutine declaration '%s' in DECLARE REDUCTION"_err_en_US,
- name.source);
- }
- return true;
- }
-
bool Pre(const parser::OmpDeclareVariantDirective &x) {
AddOmpSourceRange(x.source);
return true;
@@ -1772,14 +1766,6 @@ public:
messageHandler().set_currStmtSource(std::nullopt);
}
- bool Pre(const parser::OmpTypeName &x) {
- BeginDeclTypeSpec();
- return true;
- }
- void Post(const parser::OmpTypeName &x) { //
- EndDeclTypeSpec();
- }
-
bool Pre(const parser::OpenMPConstruct &x) {
// Indicate that the current directive is not a declarative one.
declaratives_.push_back(nullptr);
@@ -1835,6 +1821,30 @@ void OmpVisitor::Post(const parser::OmpBlockConstruct &x) {
}
}
+void OmpVisitor::Post(const parser::OmpTypeName &x) {
+ x.declTypeSpec = GetDeclTypeSpec();
+}
+
+bool OmpVisitor::Pre(const parser::OmpStylizedDeclaration &x) {
+ BeginDecl();
+ Walk(x.type.get());
+ Walk(x.var);
+ return true;
+}
+
+void OmpVisitor::Post(const parser::OmpStylizedDeclaration &x) { //
+ EndDecl();
+}
+
+bool OmpVisitor::Pre(const parser::OmpStylizedInstance &x) {
+ PushScope(Scope::Kind::OtherConstruct, nullptr);
+ return true;
+}
+
+void OmpVisitor::Post(const parser::OmpStylizedInstance &x) { //
+ PopScope();
+}
+
bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
auto &mods{OmpGetModifiers(x)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
@@ -1969,51 +1979,20 @@ void OmpVisitor::ProcessReductionSpecifier(
}
}
- auto &typeList{std::get<parser::OmpTypeNameList>(spec.t)};
-
- // Create a temporary variable declaration for the four variables
- // used in the reduction specifier and initializer (omp_out, omp_in,
- // omp_priv and omp_orig), with the type in the typeList.
- //
- // In theory it would be possible to create only variables that are
- // actually used, but that requires walking the entire parse-tree of the
- // expressions, and finding the relevant variables [there may well be other
- // variables involved too].
- //
- // This allows doing semantic analysis where the type is a derived type
- // e.g omp_out%x = omp_out%x + omp_in%x.
- //
- // These need to be temporary (in their own scope). If they are created
- // as variables in the outer scope, if there's more than one type in the
- // typelist, duplicate symbols will be reported.
- const parser::CharBlock ompVarNames[]{
- {"omp_in", 6}, {"omp_out", 7}, {"omp_priv", 8}, {"omp_orig", 8}};
-
- for (auto &t : typeList.v) {
- PushScope(Scope::Kind::OtherConstruct, nullptr);
- BeginDeclTypeSpec();
- // We need to walk t.u because Walk(t) does it's own BeginDeclTypeSpec.
- Walk(t.u);
+ reductionDetails->AddDecl(declaratives_.back());
- // Only process types we can find. There will be an error later on when
- // a type isn't found.
- if (const DeclTypeSpec *typeSpec{GetDeclTypeSpec()}) {
- reductionDetails->AddType(*typeSpec);
+ // Do not walk OmpTypeNameList. The types on the list will be visited
+ // during procesing of OmpCombinerExpression.
+ Walk(std::get<std::optional<parser::OmpCombinerExpression>>(spec.t));
+ Walk(clauses);
- for (auto &nm : ompVarNames) {
- ObjectEntityDetails details{};
- details.set_type(*typeSpec);
- MakeSymbol(nm, Attrs{}, std::move(details));
- }
+ for (auto &type : std::get<parser::OmpTypeNameList>(spec.t).v) {
+ // The declTypeSpec can be null if there is some semantic error.
+ if (type.declTypeSpec) {
+ reductionDetails->AddType(*type.declTypeSpec);
}
- EndDeclTypeSpec();
- Walk(std::get<std::optional<parser::OmpCombinerExpression>>(spec.t));
- Walk(clauses);
- PopScope();
}
- reductionDetails->AddDecl(declaratives_.back());
-
if (!symbol) {
symbol = &MakeSymbol(mangledName, Attrs{}, std::move(*reductionDetails));
}