diff options
Diffstat (limited to 'flang/lib/Semantics')
| -rw-r--r-- | flang/lib/Semantics/canonicalize-directives.cpp | 6 | ||||
| -rw-r--r-- | flang/lib/Semantics/check-call.cpp | 6 | ||||
| -rw-r--r-- | flang/lib/Semantics/check-declarations.cpp | 3 | ||||
| -rw-r--r-- | flang/lib/Semantics/check-omp-structure.cpp | 1 | ||||
| -rw-r--r-- | flang/lib/Semantics/mod-file.cpp | 3 | ||||
| -rw-r--r-- | flang/lib/Semantics/resolve-directives.cpp | 17 | ||||
| -rw-r--r-- | flang/lib/Semantics/resolve-names.cpp | 107 | 
7 files changed, 78 insertions, 65 deletions
| diff --git a/flang/lib/Semantics/canonicalize-directives.cpp b/flang/lib/Semantics/canonicalize-directives.cpp index 104df25..a651a87 100644 --- a/flang/lib/Semantics/canonicalize-directives.cpp +++ b/flang/lib/Semantics/canonicalize-directives.cpp @@ -60,7 +60,11 @@ static bool IsExecutionDirective(const parser::CompilerDirective &dir) {        std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(dir.u) ||        std::holds_alternative<parser::CompilerDirective::NoVector>(dir.u) ||        std::holds_alternative<parser::CompilerDirective::NoUnroll>(dir.u) || -      std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(dir.u); +      std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>( +          dir.u) || +      std::holds_alternative<parser::CompilerDirective::ForceInline>(dir.u) || +      std::holds_alternative<parser::CompilerDirective::Inline>(dir.u) || +      std::holds_alternative<parser::CompilerDirective::NoInline>(dir.u);  }  void CanonicalizationOfDirectives::Post(parser::SpecificationPart &spec) { diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp index c51d40b..995deaa 100644 --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -914,7 +914,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,              dummyName);        }        // INTENT(OUT) and INTENT(IN OUT) cases are caught elsewhere -    } else { +    } else if (!actualIsAllocatable && +        !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) {        messages.Say(            "ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US,            dummyName); @@ -929,7 +930,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,              dummy, actual, *scope,              /*isAssumedRank=*/dummyIsAssumedRank, actualIsPointer);        } -    } else if (!actualIsPointer) { +    } else if (!actualIsPointer && +        !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) {        messages.Say(            "Actual argument associated with POINTER %s must also be POINTER unless INTENT(IN)"_err_en_US,            dummyName); diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index 549ee83..de407d3 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -949,7 +949,8 @@ void CheckHelper::CheckObjectEntity(              "!DIR$ IGNORE_TKR(R) may not apply in an ELEMENTAL procedure"_err_en_US);        }        if (IsPassedViaDescriptor(symbol)) { -        if (IsAllocatableOrObjectPointer(&symbol)) { +        if (IsAllocatableOrObjectPointer(&symbol) && +            !ignoreTKR.test(common::IgnoreTKR::Pointer)) {            if (inExplicitExternalInterface) {              Warn(common::UsageWarning::IgnoreTKRUsage,                  "!DIR$ IGNORE_TKR should not apply to an allocatable or pointer"_warn_en_US); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index e094458f..aaaf1ec 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -3390,6 +3390,7 @@ CHECK_SIMPLE_CLAUSE(Read, OMPC_read)  CHECK_SIMPLE_CLAUSE(Threadprivate, OMPC_threadprivate)  CHECK_SIMPLE_CLAUSE(Groupprivate, OMPC_groupprivate)  CHECK_SIMPLE_CLAUSE(Threads, OMPC_threads) +CHECK_SIMPLE_CLAUSE(Threadset, OMPC_threadset)  CHECK_SIMPLE_CLAUSE(Inbranch, OMPC_inbranch)  CHECK_SIMPLE_CLAUSE(Link, OMPC_link)  CHECK_SIMPLE_CLAUSE(Indirect, OMPC_indirect) diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index 556259d..b419864 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1021,6 +1021,9 @@ void ModFileWriter::PutObjectEntity(        case common::IgnoreTKR::Contiguous:          os << 'c';          break; +      case common::IgnoreTKR::Pointer: +        os << 'p'; +        break;        }      });      os << ") " << symbol.name() << '\n'; 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 561ebd2..f88af5f 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));    } @@ -10078,7 +10057,10 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {        std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(x.u) ||        std::holds_alternative<parser::CompilerDirective::NoVector>(x.u) ||        std::holds_alternative<parser::CompilerDirective::NoUnroll>(x.u) || -      std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u)) { +      std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u) || +      std::holds_alternative<parser::CompilerDirective::ForceInline>(x.u) || +      std::holds_alternative<parser::CompilerDirective::Inline>(x.u) || +      std::holds_alternative<parser::CompilerDirective::NoInline>(x.u)) {      return;    }    if (const auto *tkr{ @@ -10127,6 +10109,9 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {                case 'c':                  set.set(common::IgnoreTKR::Contiguous);                  break; +              case 'p': +                set.set(common::IgnoreTKR::Pointer); +                break;                case 'a':                  set = common::ignoreTKRAll;                  break; | 
