================
@@ -2453,6 +2454,132 @@ static void AppendConstructTraitsForDirective(
     add(llvm::omp::TraitProperty::construct_dispatch_dispatch);
 }
 
+void AppendDirectiveContextTraits(llvm::omp::Directive directive,
+    llvm::SmallVectorImpl<llvm::omp::TraitProperty> &constructTraits) {
+  using llvm::omp::Directive;
+  using llvm::omp::TraitProperty;
+
+  for (Directive leaf : llvm::omp::getLeafConstructsOrSelf(directive)) {
+    if (leaf == Directive::OMPD_nothing ||
+        leaf == Directive::OMPD_metadirective ||
+        leaf == Directive::OMPD_unknown || leaf == Directive::OMPD_section ||
+        leaf == Directive::OMPD_dispatch ||
+        llvm::omp::getDirectiveCategory(leaf) ==
+            llvm::omp::Category::Informational) {
+      continue;
+    }
+
+    llvm::omp::VariantMatchInfo vmi;
+    AppendConstructTraitsForDirective(leaf, vmi);
+    if (vmi.RequiredTraits.test(
+            static_cast<unsigned>(TraitProperty::construct_target_target))) {
+      constructTraits.clear();
+    }
+    if (vmi.ConstructTraits.empty()) {
+      constructTraits.push_back(TraitProperty::invalid);
+    } else {
+      constructTraits.append(
+          vmi.ConstructTraits.begin(), vmi.ConstructTraits.end());
+    }
+  }
+}
+
+namespace {
+// Profile the original parse tree: folding a whole expression would lose
+// declaration identity. Parse-tree operators already unify alternate 
spellings;
+// analyze only literals to normalize their values and effective kinds.
+struct ConditionIdentity {
+  SemanticsContext &context;
+  llvm::FoldingSetNodeID id;
+
+  template <typename A> void AddNode() {
+    // Type tags and symbol addresses are local to this compilation. Profiles
+    // are rebuilt when importing symbols, never serialized as pointers.
+    static char tag;
+    id.AddPointer(&tag);
+  }
+  template <typename A> bool Pre(const A &x) {
+    AddNode<A>();
+    if constexpr (std::is_enum_v<A> || std::is_integral_v<A>)
+      id.AddInteger(static_cast<uint64_t>(x));
+    else if constexpr (std::is_same_v<A, std::string>)
+      id.AddString(x);
+    return true;
+  }
+  template <typename A> void Post(const A &) { id.AddInteger(0); }
+  // CharBlocks in expression nodes carry source locations, not structure.
+  bool Pre(const parser::CharBlock &) { return false; }
+  bool Pre(const parser::Name &name) {
+    AddNode<parser::Name>();
+    if (name.symbol)
+      id.AddPointer(&name.symbol->GetUltimate());
+    else
+      id.AddString(name.source.ToString());
+    return false;
+  }
+  bool Pre(const parser::SignedIntLiteralConstant &literal) {
+    AddNode<parser::SignedIntLiteralConstant>();
+    auto value{evaluate::ExpressionAnalyzer{context}.Analyze(literal)};
+    CHECK(value);
+    id.AddString(value->AsFortran());
+    return false;
+  }
+  bool Pre(const parser::SignedRealLiteralConstant &literal) {
+    AddNode<parser::SignedRealLiteralConstant>();
+    auto value{evaluate::ExpressionAnalyzer{context}.Analyze(literal)};
+    CHECK(value);
+    id.AddString(value->AsFortran());
+    return false;
+  }
+  bool Pre(const parser::Expr &expr) {
+    if (const auto *parens{std::get_if<parser::Expr::Parentheses>(&expr.u)}) {
+      parser::Walk(parens->v.value(), *this);
----------------
MattPD wrote:

Confirmed at 3080eca: Flang's condition identity again ignores only outer 
parentheses, matching Clang.

https://github.com/llvm/llvm-project/pull/224431
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to