forked from OSchip/llvm-project
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:
parent
096619eb52
commit
0b66eb38c7
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue