aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-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);