aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCXXScopeSpec.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-02-21 18:36:56 +0000
committerDouglas Gregor <dgregor@apple.com>2010-02-21 18:36:56 +0000
commitb10cd04880672103660e5844e51ee91af7361a20 (patch)
tree6ea428d3b9d0b09b9533f8bec9ff66f2392dc74c /lib/Sema/SemaCXXScopeSpec.cpp
parent12116062c8243c6f88d79dac9663a359b77741c6 (diff)
Implement support for parsing pseudo-destructor expression with a nested-name-specifier, e.g.,
typedef int Int; int *p; p->Int::~Int(); This weakens the invariant that the only types in nested-name-specifiers are tag types (restricted to class types in C++98/03). However, we weaken this invariant as little as possible, accepting arbitrary types in nested-name-specifiers only when we're in a member access expression that looks like a pseudo-destructor expression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96743 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCXXScopeSpec.cpp')
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp42
1 files changed, 28 insertions, 14 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 52e9e9bc87..315938d2d4 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -176,16 +176,15 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
- const TagType *Tag = NNS->getAsType()->getAs<TagType>();
- assert(Tag && "Non-tag type in nested-name-specifier");
- return Tag->getDecl();
- } break;
+ if (const TagType *Tag = NNS->getAsType()->getAs<TagType>())
+ return Tag->getDecl();
+ break;
+ }
case NestedNameSpecifier::Global:
return Context.getTranslationUnitDecl();
}
- // Required to silence a GCC warning.
return 0;
}
@@ -270,7 +269,8 @@ Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S,
/// \brief Determines whether the given declaration is an valid acceptable
/// result for name lookup of a nested-name-specifier.
-bool Sema::isAcceptableNestedNameSpecifier(NamedDecl *SD) {
+bool Sema::isAcceptableNestedNameSpecifier(NamedDecl *SD,
+ bool MayBePseudoDestructor) {
if (!SD)
return false;
@@ -281,6 +281,11 @@ bool Sema::isAcceptableNestedNameSpecifier(NamedDecl *SD) {
if (!isa<TypeDecl>(SD))
return false;
+ // If this may be part of a pseudo-destructor expression, we'll
+ // accept any type.
+ if (MayBePseudoDestructor)
+ return true;
+
// Determine whether we have a class (or, in C++0x, an enum) or
// a typedef thereof. If so, build the nested-name-specifier.
QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
@@ -321,7 +326,7 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
return 0;
NamedDecl *Result = Found.getFoundDecl();
- if (isAcceptableNestedNameSpecifier(Result))
+ if (isAcceptableNestedNameSpecifier(Result, true))
return Result;
return 0;
@@ -345,6 +350,7 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
SourceLocation IdLoc,
SourceLocation CCLoc,
IdentifierInfo &II,
+ bool MayBePseudoDestructor,
QualType ObjectType,
NamedDecl *ScopeLookupResult,
bool EnteringContext,
@@ -439,7 +445,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
DeclarationName Name = Found.getLookupName();
if (CorrectTypo(Found, S, &SS, LookupCtx, EnteringContext) &&
Found.isSingleResult() &&
- isAcceptableNestedNameSpecifier(Found.getAsSingle<NamedDecl>())) {
+ isAcceptableNestedNameSpecifier(Found.getAsSingle<NamedDecl>(),
+ MayBePseudoDestructor)) {
if (LookupCtx)
Diag(Found.getNameLoc(), diag::err_no_member_suggest)
<< Name << LookupCtx << Found.getLookupName() << SS.getRange()
@@ -459,7 +466,7 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
}
NamedDecl *SD = Found.getAsSingle<NamedDecl>();
- if (isAcceptableNestedNameSpecifier(SD)) {
+ if (isAcceptableNestedNameSpecifier(SD, MayBePseudoDestructor)) {
if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) {
// C++ [basic.lookup.classref]p4:
// [...] If the name is found in both contexts, the
@@ -471,13 +478,14 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// scope, reconstruct the result from the template instantiation itself.
NamedDecl *OuterDecl;
if (S) {
- LookupResult FoundOuter(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+ LookupResult FoundOuter(*this, &II, IdLoc,
+ LookupNestedNameSpecifierName);
LookupName(FoundOuter, S);
OuterDecl = FoundOuter.getAsSingle<NamedDecl>();
} else
OuterDecl = ScopeLookupResult;
- if (isAcceptableNestedNameSpecifier(OuterDecl) &&
+ if (isAcceptableNestedNameSpecifier(OuterDecl, MayBePseudoDestructor) &&
OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
(!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
!Context.hasSameType(
@@ -554,9 +562,11 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
SourceLocation IdLoc,
SourceLocation CCLoc,
IdentifierInfo &II,
+ bool MayBePseudoDestructor,
TypeTy *ObjectTypePtr,
bool EnteringContext) {
return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
+ MayBePseudoDestructor,
QualType::getFromOpaquePtr(ObjectTypePtr),
/*ScopeLookupResult=*/0, EnteringContext,
false);
@@ -569,10 +579,13 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
///
/// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
bool Sema::IsInvalidUnlessNestedName(Scope *S, const CXXScopeSpec &SS,
- IdentifierInfo &II, TypeTy *ObjectType,
+ IdentifierInfo &II,
+ bool MayBePseudoDestructor,
+ TypeTy *ObjectType,
bool EnteringContext) {
return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
- II, QualType::getFromOpaquePtr(ObjectType),
+ II, MayBePseudoDestructor,
+ QualType::getFromOpaquePtr(ObjectType),
/*ScopeLookupResult=*/0, EnteringContext,
true);
}
@@ -581,7 +594,8 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
const CXXScopeSpec &SS,
TypeTy *Ty,
SourceRange TypeRange,
- SourceLocation CCLoc) {
+ SourceLocation CCLoc,
+ bool MayBePseudoDestructor) {
NestedNameSpecifier *Prefix
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
QualType T = GetTypeFromParser(Ty);