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.

llvm-svn: 102818
This commit is contained in:
John McCall 2010-05-01 00:40:08 +00:00
parent 096619eb52
commit 0b66eb38c7
8 changed files with 48 additions and 60 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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());

View File

@ -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);
CXXScopeSpec SS;
SS.setScopeRep(NNS);
SS.setRange(Range);
// 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.
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);
}
DeclContext *Ctx = 0;
// 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.
if (CurrentInstantiation)
Ctx = CurrentInstantiation;
else {
CXXScopeSpec SS;
SS.setScopeRep(NNS);
SS.setRange(Range);
if (RequireCompleteDeclContext(SS))
return QualType();
Ctx = computeDeclContext(SS);
}
assert(Ctx && "No declaration context?");
if (RequireCompleteDeclContext(SS, Ctx))
return QualType();
DeclarationName Name(&II);
LookupResult Result(*this, Name, Range.getEnd(), LookupOrdinaryName);