aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-05-01 00:40:08 +0000
committerJohn McCall <rjmccall@apple.com>2010-05-01 00:40:08 +0000
commit77bb1aa78bcd26e42c0382043e65a2b03242be4d (patch)
tree89f763410c2fae9ecf90794c55bef618b65a9d42
parentcdb65d8724428664af7394451863b4aa6123f52b (diff)
It turns out that basically every caller to RequireCompleteDeclContext
already knows what context it's looking in. Just pass that context in instead of (questionably) recalculating it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102818 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp27
-rw-r--r--lib/Sema/SemaCodeComplete.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp15
-rw-r--r--lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--lib/Sema/SemaExpr.cpp4
-rw-r--r--lib/Sema/SemaLookup.cpp2
-rw-r--r--lib/Sema/SemaTemplate.cpp54
8 files changed, 49 insertions, 61 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index a5b43e8a04..a79b0007f7 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2365,7 +2365,7 @@ public:
virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
// Marks SS invalid if it represents an incomplete type.
- bool RequireCompleteDeclContext(CXXScopeSpec &SS);
+ bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC);
DeclContext *computeDeclContext(QualType T);
DeclContext *computeDeclContext(const CXXScopeSpec &SS,
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 10adc6762f..c0ec9e997d 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -186,21 +186,10 @@ CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) {
/// that is currently being defined. Or, if we have a type that names
/// a class template specialization that is not a complete type, we
/// will attempt to instantiate that class template.
-bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS) {
- if (!SS.isSet() || SS.isInvalid())
- return false;
+bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
+ DeclContext *DC) {
+ assert(DC != 0 && "given null context");
- DeclContext *DC = computeDeclContext(SS, true);
- if (!DC) {
- // It's dependent.
- assert(isDependentScopeSpecifier(SS) &&
- "No context for non-dependent scope specifier?");
- Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
- << SS.getRange();
- SS.setScopeRep(0);
- return true;
- }
-
if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
// If this is a dependent type, then we consider it complete.
if (Tag->isDependentContext())
@@ -216,7 +205,7 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS) {
if (RequireCompleteType(SS.getRange().getBegin(),
Context.getTypeDeclType(Tag),
PDiag(diag::err_incomplete_nested_name_spec)
- << SS.getRange())) {
+ << SS.getRange())) {
SS.setScopeRep(0); // Mark the ScopeSpec invalid.
return true;
}
@@ -322,7 +311,8 @@ bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
// nested-name-specifier.
// The declaration context must be complete.
- if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
+ if (!LookupCtx->isDependentContext() &&
+ RequireCompleteDeclContext(SS, LookupCtx))
return false;
LookupQualifiedName(Found, LookupCtx);
@@ -392,7 +382,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// nested-name-specifier.
// The declaration context must be complete.
- if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
+ if (!LookupCtx->isDependentContext() &&
+ RequireCompleteDeclContext(SS, LookupCtx))
return 0;
LookupQualifiedName(Found, LookupCtx);
@@ -656,7 +647,7 @@ bool Sema::ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS) {
// Before we enter a declarator's context, we need to make sure that
// it is a complete declaration context.
- if (!DC->isDependentContext() && RequireCompleteDeclContext(SS))
+ if (!DC->isDependentContext() && RequireCompleteDeclContext(SS, DC))
return true;
EnterDeclaratorContext(S, DC);
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 35bb6977ef..c075d16170 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2286,7 +2286,7 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
// Try to instantiate any non-dependent declaration contexts before
// we look in them.
- if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
+ if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
return;
ResultBuilder Results(*this);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7a70c32877..3e4c923285 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -97,7 +97,8 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
return 0;
}
- if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS))
+ if (!LookupCtx->isDependentContext() &&
+ RequireCompleteDeclContext(*SS, LookupCtx))
return 0;
}
@@ -2030,7 +2031,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
bool IsDependentContext = DC->isDependentContext();
if (!IsDependentContext &&
- RequireCompleteDeclContext(D.getCXXScopeSpec()))
+ RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
return DeclPtrTy();
if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
@@ -4940,12 +4941,18 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
IsDependent = true;
return DeclPtrTy();
}
+ } else {
+ DC = computeDeclContext(SS, true);
+ if (!DC) {
+ Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
+ << SS.getRange();
+ return DeclPtrTy();
+ }
}
- if (RequireCompleteDeclContext(SS))
+ if (RequireCompleteDeclContext(SS, DC))
return DeclPtrTy::make((Decl *)0);
- DC = computeDeclContext(SS, true);
SearchDC = DC;
// Look-up name inside 'foo::'.
LookupQualifiedName(Previous, DC);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 854f204ab0..c73c6caf29 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3724,7 +3724,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
if (!LookupContext) return D;
UsingDecl *UD = cast<UsingDecl>(D);
- if (RequireCompleteDeclContext(SS)) {
+ if (RequireCompleteDeclContext(SS, LookupContext)) {
UD->setInvalidDecl();
return UD;
}
@@ -5251,11 +5251,11 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
ForRedeclaration);
if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
- // FIXME: RequireCompleteDeclContext
DC = computeDeclContext(ScopeQual);
// FIXME: handle dependent contexts
if (!DC) return DeclPtrTy();
+ if (RequireCompleteDeclContext(ScopeQual, DC)) return DeclPtrTy();
LookupQualifiedName(Previous, DC);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d8d525e992..a1b66cd946 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1238,7 +1238,7 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext())
return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0);
- if (RequireCompleteDeclContext(SS))
+ if (RequireCompleteDeclContext(SS, DC))
return ExprError();
LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
@@ -2582,7 +2582,7 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
// nested-name-specifier.
DC = SemaRef.computeDeclContext(SS, false);
- if (SemaRef.RequireCompleteDeclContext(SS)) {
+ if (SemaRef.RequireCompleteDeclContext(SS, DC)) {
SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag)
<< SS.getRange() << DC;
return true;
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index bdbbc119c6..337a4a3ce3 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1261,7 +1261,7 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
if (DeclContext *DC = computeDeclContext(*SS, EnteringContext)) {
// We have resolved the scope specifier to a particular declaration
// contex, and will perform name lookup in that context.
- if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS))
+ if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS, DC))
return false;
R.setContextRange(SS->getRange());
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 56410a2cfa..694b21c839 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -210,7 +210,7 @@ void Sema::LookupTemplateName(LookupResult &Found,
isDependent = isDependentScopeSpecifier(SS);
// The declaration context must be complete.
- if (LookupCtx && RequireCompleteDeclContext(SS))
+ if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx))
return;
}
@@ -753,15 +753,15 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
LookupResult Previous(*this, Name, NameLoc, LookupOrdinaryName,
ForRedeclaration);
if (SS.isNotEmpty() && !SS.isInvalid()) {
- if (RequireCompleteDeclContext(SS))
- return true;
-
SemanticContext = computeDeclContext(SS, true);
if (!SemanticContext) {
// FIXME: Produce a reasonable diagnostic here
return true;
}
+ if (RequireCompleteDeclContext(SS, SemanticContext))
+ return true;
+
LookupQualifiedName(Previous, SemanticContext);
} else {
SemanticContext = CurContext;
@@ -1633,7 +1633,7 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
DeclContext *DC;
if (!(DC = computeDeclContext(SS, false)) ||
DC->isDependentContext() ||
- RequireCompleteDeclContext(SS))
+ RequireCompleteDeclContext(SS, DC))
return BuildDependentDeclRefExpr(SS, Name, NameLoc, &TemplateArgs);
LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
@@ -5260,36 +5260,26 @@ QualType
Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, const IdentifierInfo &II,
SourceRange Range) {
- CXXRecordDecl *CurrentInstantiation = 0;
- if (NNS->isDependent()) {
- CurrentInstantiation = getCurrentInstantiationOf(NNS);
-
- // If the nested-name-specifier does not refer to the current
- // instantiation, then build a typename type.
- if (!CurrentInstantiation)
- return Context.getDependentNameType(Keyword, NNS, &II);
-
- // The nested-name-specifier refers to the current instantiation, so the
- // "typename" keyword itself is superfluous. In C++03, the program is
- // actually ill-formed. However, DR 382 (in C++0x CD1) allows such
- // extraneous "typename" keywords, and we retroactively apply this DR to
- // C++03 code.
- }
+ CXXScopeSpec SS;
+ SS.setScopeRep(NNS);
+ SS.setRange(Range);
- DeclContext *Ctx = 0;
+ DeclContext *Ctx = computeDeclContext(SS);
+ if (!Ctx) {
+ // If the nested-name-specifier is dependent and couldn't be
+ // resolved to a type, build a typename type.
+ assert(NNS->isDependent());
+ return Context.getDependentNameType(Keyword, NNS, &II);
+ }
- if (CurrentInstantiation)
- Ctx = CurrentInstantiation;
- else {
- CXXScopeSpec SS;
- SS.setScopeRep(NNS);
- SS.setRange(Range);
- if (RequireCompleteDeclContext(SS))
- return QualType();
+ // If the nested-name-specifier refers to the current instantiation,
+ // the "typename" keyword itself is superfluous. In C++03, the
+ // program is actually ill-formed. However, DR 382 (in C++0x CD1)
+ // allows such extraneous "typename" keywords, and we retroactively
+ // apply this DR to C++03 code. In any case we continue.
- Ctx = computeDeclContext(SS);
- }
- assert(Ctx && "No declaration context?");
+ if (RequireCompleteDeclContext(SS, Ctx))
+ return QualType();
DeclarationName Name(&II);
LookupResult Result(*this, Name, Range.getEnd(), LookupOrdinaryName);