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
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index a596086..11c19eb 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -265,6 +265,7 @@
/// alternate behavior.
NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range,
+ bool MayBePseudoDestructor,
QualType ObjectType = QualType(),
NamedDecl *FirstQualifierInScope = 0);
@@ -555,6 +556,7 @@
NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
SourceRange Range,
IdentifierInfo &II,
+ bool MayBePseudoDestructor,
QualType ObjectType,
NamedDecl *FirstQualifierInScope);
@@ -577,7 +579,8 @@
NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
SourceRange Range,
bool TemplateKW,
- QualType T);
+ QualType T,
+ bool MayBePseudoDestructor);
/// \brief Build a new template name given a nested name specifier, a flag
/// indicating whether the "template" keyword was provided, and the template
@@ -1725,6 +1728,7 @@
NestedNameSpecifier *
TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range,
+ bool MayBePseudoDestructor,
QualType ObjectType,
NamedDecl *FirstQualifierInScope) {
if (!NNS)
@@ -1734,6 +1738,7 @@
NestedNameSpecifier *Prefix = NNS->getPrefix();
if (Prefix) {
Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
+ false,
ObjectType,
FirstQualifierInScope);
if (!Prefix)
@@ -1755,6 +1760,7 @@
return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
*NNS->getAsIdentifier(),
+ MayBePseudoDestructor,
ObjectType,
FirstQualifierInScope);
@@ -1790,7 +1796,8 @@
return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
- T);
+ T,
+ MayBePseudoDestructor);
}
}
@@ -1842,6 +1849,7 @@
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
/*FIXME:*/SourceRange(getDerived().getBaseLocation()),
+ false,
ObjectType);
if (!NNS)
return TemplateName();
@@ -1869,6 +1877,7 @@
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
/*FIXME:*/SourceRange(getDerived().getBaseLocation()),
+ false,
ObjectType);
if (!NNS && DTN->getQualifier())
return TemplateName();
@@ -2928,6 +2937,7 @@
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(),
SourceRange(),
+ false,
ObjectType);
if (!NNS)
return QualType();
@@ -2962,7 +2972,7 @@
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR,
- ObjectType);
+ false, ObjectType);
if (!NNS)
return QualType();
@@ -3598,7 +3608,8 @@
NestedNameSpecifier *Qualifier = 0;
if (E->getQualifier()) {
Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
+ E->getQualifierRange(),
+ false);
if (!Qualifier)
return SemaRef.ExprError();
}
@@ -3807,7 +3818,8 @@
if (E->hasQualifier()) {
Qualifier
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
+ E->getQualifierRange(),
+ false);
if (Qualifier == 0)
return SemaRef.ExprError();
}
@@ -4677,7 +4689,8 @@
NestedNameSpecifier *Qualifier
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
+ E->getQualifierRange(),
+ true);
if (E->getQualifier() && !Qualifier)
return SemaRef.ExprError();
@@ -4747,7 +4760,8 @@
NestedNameSpecifier *Qualifier = 0;
if (Old->getQualifier()) {
Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
- Old->getQualifierRange());
+ Old->getQualifierRange(),
+ false);
if (!Qualifier)
return SemaRef.ExprError();
@@ -4803,7 +4817,8 @@
DependentScopeDeclRefExpr *E) {
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
+ E->getQualifierRange(),
+ false);
if (!NNS)
return SemaRef.ExprError();
@@ -5050,8 +5065,11 @@
NestedNameSpecifier *Qualifier = 0;
if (E->getQualifier()) {
+ bool MayBePseudoDestructor
+ = E->getMember().getNameKind() == DeclarationName::CXXDestructorName;
Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange(),
+ MayBePseudoDestructor,
ObjectType,
FirstQualifierInScope);
if (!Qualifier)
@@ -5126,7 +5144,8 @@
if (Old->getQualifier()) {
Qualifier
= getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
- Old->getQualifierRange());
+ Old->getQualifierRange(),
+ false);
if (Qualifier == 0)
return SemaRef.ExprError();
}
@@ -5551,6 +5570,7 @@
TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
SourceRange Range,
IdentifierInfo &II,
+ bool MayBePseudoDestructor,
QualType ObjectType,
NamedDecl *FirstQualifierInScope) {
CXXScopeSpec SS;
@@ -5560,6 +5580,7 @@
return static_cast<NestedNameSpecifier *>(
SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Range.getEnd(), II,
+ MayBePseudoDestructor,
ObjectType,
FirstQualifierInScope,
false, false));
@@ -5578,8 +5599,9 @@
TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
SourceRange Range,
bool TemplateKW,
- QualType T) {
- if (T->isDependentType() || T->isRecordType() ||
+ QualType T,
+ bool MayBePseudoDestructor) {
+ if (MayBePseudoDestructor || T->isDependentType() || T->isRecordType() ||
(SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
assert(!T.hasLocalQualifiers() && "Can't get cv-qualifiers here");
return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,