[PATCH] D116029: [clang][NFC] Refactor coroutine_traits lookup

Nathan Sidwell via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 21 07:29:30 PST 2021


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd4de2a4d5905: [clang][NFC] Refactor coroutine_traits lookup (authored by urnathan).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D116029?vs=395504&id=395676#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116029/new/

https://reviews.llvm.org/D116029

Files:
  clang/lib/Sema/SemaCoroutine.cpp


Index: clang/lib/Sema/SemaCoroutine.cpp
===================================================================
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -1661,45 +1661,53 @@
                                                SourceLocation FuncLoc,
                                                NamespaceDecl *&Namespace) {
   if (!StdCoroutineTraitsCache) {
-    NamespaceDecl *CoroNamespace = getStdNamespace();
-    LookupResult Result(*this, &PP.getIdentifierTable().get("coroutine_traits"),
-                        FuncLoc, LookupOrdinaryName);
-
-    if (!CoroNamespace || !LookupQualifiedName(Result, CoroNamespace)) {
-      /// Look up in namespace std::experimental, for compatibility.
-      /// TODO: Remove this extra lookup when <experimental/coroutine> is
-      /// removed.
-      CoroNamespace = lookupStdExperimentalNamespace();
-      if (!CoroNamespace || !LookupQualifiedName(Result, CoroNamespace)) {
-        Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
-            << "std::coroutine_traits";
-        return nullptr;
-      }
+    // Because coroutines moved from std::experimental in the TS to std in
+    // C++20, we look in both places to give users time to transition their
+    // TS-specific code to C++20.  Diagnostics are given when the TS usage is
+    // discovered.
+    // TODO: Become stricter when <experimental/coroutine> is removed.
+
+    auto const &TraitIdent = PP.getIdentifierTable().get("coroutine_traits");
+
+    NamespaceDecl *StdSpace = getStdNamespace();
+    LookupResult ResStd(*this, &TraitIdent, FuncLoc, LookupOrdinaryName);
+    bool InStd = StdSpace && LookupQualifiedName(ResStd, StdSpace);
+
+    NamespaceDecl *ExpSpace = lookupStdExperimentalNamespace();
+    LookupResult ResExp(*this, &TraitIdent, FuncLoc, LookupOrdinaryName);
+    bool InExp = ExpSpace && LookupQualifiedName(ResExp, ExpSpace);
+
+    if (!InStd && !InExp) {
+      // The goggles, they found nothing!
+      Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
+          << "std::coroutine_traits";
+      return nullptr;
+    }
+
+    if (!InStd) {
+      // Found only in std::experimental.
       Diag(KwLoc, diag::warn_deprecated_coroutine_namespace)
           << "coroutine_traits";
-    } else {
-      /// When we found coroutine_traits in std namespace. Make sure there is no
-      /// misleading definition in std::experimental namespace.
-      NamespaceDecl *ExpNamespace = lookupStdExperimentalNamespace();
-      LookupResult ExpResult(*this,
-                             &PP.getIdentifierTable().get("coroutine_traits"),
-                             FuncLoc, LookupOrdinaryName);
-      if (ExpNamespace && LookupQualifiedName(ExpResult, ExpNamespace)) {
-        Diag(KwLoc,
-             diag::err_mixed_use_std_and_experimental_namespace_for_coroutine);
-        Diag(KwLoc, diag::warn_deprecated_coroutine_namespace)
-            << "coroutine_traits";
-        return nullptr;
-      }
+    } else if (InExp) {
+      // Found in std and std::experimental.
+      Diag(KwLoc,
+           diag::err_mixed_use_std_and_experimental_namespace_for_coroutine);
+      Diag(KwLoc, diag::warn_deprecated_coroutine_namespace)
+          << "coroutine_traits";
+      return nullptr;
     }
 
+    // Prefer ::std to std::experimental.
+    auto &Result = InStd ? ResStd : ResExp;
+    CoroTraitsNamespaceCache = InStd ? StdSpace : ExpSpace;
+
+    // coroutine_traits is required to be a class template.
     if (!(StdCoroutineTraitsCache = Result.getAsSingle<ClassTemplateDecl>())) {
       Result.suppressDiagnostics();
       NamedDecl *Found = *Result.begin();
       Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
       return nullptr;
     }
-    CoroTraitsNamespaceCache = CoroNamespace;
   }
   Namespace = CoroTraitsNamespaceCache;
   return StdCoroutineTraitsCache;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D116029.395676.patch
Type: text/x-patch
Size: 3899 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211221/7d5e317a/attachment.bin>


More information about the cfe-commits mailing list