aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-04-24 05:37:28 +0000
committerDouglas Gregor <dgregor@apple.com>2011-04-24 05:37:28 +0000
commit312eadb832cab4497a069409954500d8192b8f0d (patch)
treef919e5f5b0f8f0e2092ee948b86f92a7171697a2 /lib/Sema/SemaTemplate.cpp
parent1b6005285e234bc30698917b2d3abb2f1f98bc77 (diff)
Implement a new identifier-classification scheme where Sema
performs name lookup for an identifier and resolves it to a type/expression/template/etc. in the same step. This scheme is intended to improve both performance (by reducing the number of redundant name lookups for a given identifier token) and error recovery (by giving Sema a chance to correct type names before the parser has decided that the identifier isn't a type name). For example, this allows us to properly typo-correct type names at the beginning of a statement: t.c:6:3: error: use of undeclared identifier 'integer'; did you mean 'Integer'? integer *i = 0; ^~~~~~~ Integer t.c:1:13: note: 'Integer' declared here typedef int Integer; ^ Previously, we wouldn't give a Fix-It because the typo correction occurred after the parser had checked whether "integer" was a type name (via Sema::getTypeName(), which isn't allowed to typo-correct) and therefore decided to parse "integer * i = 0" as an expression. By typo-correcting earlier, we typo-correct to the type name Integer and parse this as a declaration. Moreover, in this context, we can also typo-correct identifiers to keywords, e.g., t.c:7:3: error: use of undeclared identifier 'vid'; did you mean 'void'? vid *p = i; ^~~ void and recover appropriately. Note that this is very much a work-in-progress. The new Sema::ClassifyName is only used for expression-or-declaration disambiguation in C at the statement level. The next steps will be to make this work for the same disambiguation in C++ (where functional-style casts make some trouble), then push it further into the parser to eliminate more redundant name lookups. Fixes <rdar://problem/7963833> for C and starts us down the path of <rdar://problem/8172000>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130082 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp18
1 files changed, 13 insertions, 5 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 08eb654236..bc29a4cbdc 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -76,13 +76,13 @@ static NamedDecl *isAcceptableTemplateName(ASTContext &Context,
return 0;
}
-static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
+void Sema::FilterAcceptableTemplateNames(LookupResult &R) {
// The set of class templates we've already seen.
llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates;
LookupResult::Filter filter = R.makeFilter();
while (filter.hasNext()) {
NamedDecl *Orig = filter.next();
- NamedDecl *Repl = isAcceptableTemplateName(C, Orig);
+ NamedDecl *Repl = isAcceptableTemplateName(Context, Orig);
if (!Repl)
filter.erase();
else if (Repl != Orig) {
@@ -114,6 +114,14 @@ static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
filter.done();
}
+bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R) {
+ for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I)
+ if (isAcceptableTemplateName(Context, *I))
+ return true;
+
+ return true;
+}
+
TemplateNameKind Sema::isTemplateName(Scope *S,
CXXScopeSpec &SS,
bool hasTemplateKeyword,
@@ -289,7 +297,7 @@ void Sema::LookupTemplateName(LookupResult &Found,
DeclarationName Name = Found.getLookupName();
if (DeclarationName Corrected = CorrectTypo(Found, S, &SS, LookupCtx,
false, CTC_CXXCasts)) {
- FilterAcceptableTemplateNames(Context, Found);
+ FilterAcceptableTemplateNames(Found);
if (!Found.empty()) {
if (LookupCtx)
Diag(Found.getNameLoc(), diag::err_no_member_template_suggest)
@@ -311,7 +319,7 @@ void Sema::LookupTemplateName(LookupResult &Found,
}
}
- FilterAcceptableTemplateNames(Context, Found);
+ FilterAcceptableTemplateNames(Found);
if (Found.empty()) {
if (isDependent)
MemberOfUnknownSpecialization = true;
@@ -327,7 +335,7 @@ void Sema::LookupTemplateName(LookupResult &Found,
LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(),
LookupOrdinaryName);
LookupName(FoundOuter, S);
- FilterAcceptableTemplateNames(Context, FoundOuter);
+ FilterAcceptableTemplateNames(FoundOuter);
if (FoundOuter.empty()) {
// - if the name is not found, the name found in the class of the