[clang] d4de2a4 - [clang][NFC] Refactor coroutine_traits lookup
Nathan Sidwell via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 21 07:29:18 PST 2021
Author: Nathan Sidwell
Date: 2021-12-21T10:29:01-05:00
New Revision: d4de2a4d5905beb0602a615593daf003378ddb64
URL: https://github.com/llvm/llvm-project/commit/d4de2a4d5905beb0602a615593daf003378ddb64
DIFF: https://github.com/llvm/llvm-project/commit/d4de2a4d5905beb0602a615593daf003378ddb64.diff
LOG: [clang][NFC] Refactor coroutine_traits lookup
To allow transition from the TS-specified
std::experimental::coroutine_traits to the C++20-specified
std::coroutine_traits, we lookup in both places and provide helpful
diagnostics. This refactors the code to avoid separate paths to
std::experimental lookups.
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D116029
Added:
Modified:
clang/lib/Sema/SemaCoroutine.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index d4a919e8c1656..27ba49fb001c0 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -1661,45 +1661,53 @@ ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
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;
More information about the cfe-commits
mailing list