Add caching when looking up coroutine_traits
Summary:
Currently clang looks up the coroutine_traits ClassTemplateDecl
everytime it looks up the promise type. This is unnecessary
as coroutine_traits doesn't change between promise type lookups.
This diff caches the coroutine_traits lookup.
Patch by Tanoy Sinha!
Test Plan:
I added log statements in the new lookupCoroutineTraits function
to ensure that LookupQualifiedName was only called once even
when multiple coroutines existed in the source file.
Reviewers: modocache, GorNishanov
Reviewed By: modocache
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D48981
llvm-svn: 337103
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 658bdcb..1d5454c 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -60,20 +60,8 @@
return QualType();
}
- LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_traits"),
- FuncLoc, Sema::LookupOrdinaryName);
- if (!S.LookupQualifiedName(Result, StdExp)) {
- S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
- << "std::experimental::coroutine_traits";
- return QualType();
- }
-
- ClassTemplateDecl *CoroTraits = Result.getAsSingle<ClassTemplateDecl>();
+ ClassTemplateDecl *CoroTraits = S.lookupCoroutineTraits(KwLoc, FuncLoc);
if (!CoroTraits) {
- Result.suppressDiagnostics();
- // We found something weird. Complain about the first thing we found.
- NamedDecl *Found = *Result.begin();
- S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
return QualType();
}
@@ -1538,3 +1526,27 @@
return StmtError();
return Res;
}
+
+ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
+ SourceLocation FuncLoc) {
+ if (!StdCoroutineTraitsCache) {
+ if (auto StdExp = lookupStdExperimentalNamespace()) {
+ LookupResult Result(*this,
+ &PP.getIdentifierTable().get("coroutine_traits"),
+ FuncLoc, LookupOrdinaryName);
+ if (!LookupQualifiedName(Result, StdExp)) {
+ Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
+ << "std::experimental::coroutine_traits";
+ return nullptr;
+ }
+ if (!(StdCoroutineTraitsCache =
+ Result.getAsSingle<ClassTemplateDecl>())) {
+ Result.suppressDiagnostics();
+ NamedDecl *Found = *Result.begin();
+ Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
+ return nullptr;
+ }
+ }
+ }
+ return StdCoroutineTraitsCache;
+}