Eliminate CXXAdornedMemberExpr entirely. Instead, optionally allocate
space within the MemberExpr for the nested-name-specifier and its
source range. We'll do the same thing with explicitly-specified
template arguments, assuming I don't flip-flop again.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80642 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 6bc4854..5b583a5 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -262,6 +262,36 @@
return FnType->getResultType();
}
+MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
+ SourceRange qualrange, NamedDecl *memberdecl,
+ SourceLocation l, QualType ty)
+ : Expr(MemberExprClass, ty,
+ base->isTypeDependent() || (qual && qual->isDependent()),
+ base->isValueDependent() || (qual && qual->isDependent())),
+ Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
+ HasQualifier(qual != 0) {
+ // Initialize the qualifier, if any.
+ if (HasQualifier) {
+ NameQualifier *NQ = getMemberQualifier();
+ NQ->NNS = qual;
+ NQ->Range = qualrange;
+ }
+}
+
+MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
+ NestedNameSpecifier *qual,
+ SourceRange qualrange,
+ NamedDecl *memberdecl,
+ SourceLocation l, QualType ty) {
+ std::size_t Size = sizeof(MemberExpr);
+ if (qual != 0)
+ Size += sizeof(NameQualifier);
+
+ void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
+ return new (Mem) MemberExpr(base, isarrow, qual, qualrange, memberdecl, l,
+ ty);
+}
+
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "<<=".
const char *BinaryOperator::getOpcodeStr(Opcode Op) {
@@ -498,7 +528,6 @@
}
case MemberExprClass:
- case CXXAdornedMemberExprClass:
// If the base pointer or element is to a volatile pointer/field, accessing
// it is a side effect.
if (getType().isVolatileQualified())
@@ -686,8 +715,7 @@
return LV_Valid;
break;
}
- case MemberExprClass:
- case CXXAdornedMemberExprClass: {
+ case MemberExprClass: {
const MemberExpr *m = cast<MemberExpr>(this);
if (Ctx.getLangOptions().CPlusPlus) { // C++ [expr.ref]p4:
NamedDecl *Member = m->getMemberDecl();
@@ -958,8 +986,7 @@
}
return false;
}
- case MemberExprClass:
- case CXXAdornedMemberExprClass: {
+ case MemberExprClass: {
const MemberExpr *M = cast<MemberExpr>(this);
return M->getBase()->isOBJCGCCandidate(Ctx);
}
@@ -1917,13 +1944,6 @@
Stmt::child_iterator MemberExpr::child_begin() { return &Base; }
Stmt::child_iterator MemberExpr::child_end() { return &Base+1; }
-bool MemberExpr::hasQualifier() const {
- if (const CXXAdornedMemberExpr *A = dyn_cast<CXXAdornedMemberExpr>(this))
- return A->hasQualifier();
-
- return false;
-}
-
// ExtVectorElementExpr
Stmt::child_iterator ExtVectorElementExpr::child_begin() { return &Base; }
Stmt::child_iterator ExtVectorElementExpr::child_end() { return &Base+1; }
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index d09358c..4be4a8a 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -739,6 +739,9 @@
OS << (Node->isArrow() ? "->" : ".");
// FIXME: Suppress printing references to unnamed objects
// representing anonymous unions/structs
+ if (NestedNameSpecifier *Qualifier = Node->getQualifier())
+ Qualifier->print(OS, Policy);
+
OS << Node->getMemberDecl()->getNameAsString();
}
void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
@@ -1126,16 +1129,6 @@
OS << ")";
}
-void StmtPrinter::VisitCXXAdornedMemberExpr(CXXAdornedMemberExpr *Node) {
- // FIXME: Suppress printing implicit bases (like "this")
- PrintExpr(Node->getBase());
- OS << (Node->isArrow() ? "->" : ".");
- // FIXME: Suppress printing references to unnamed objects
- // representing anonymous unions/structs
- Node->getQualifier()->print(OS, Policy);
- OS << Node->getMemberDecl()->getNameAsString();
-}
-
void StmtPrinter::VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *Node) {
PrintExpr(Node->getBase());
OS << (Node->isArrow() ? "->" : ".");
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 8ce620c..2545d34 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -272,6 +272,7 @@
void StmtProfiler::VisitMemberExpr(MemberExpr *S) {
VisitExpr(S);
VisitDecl(S->getMemberDecl());
+ VisitNestedNameSpecifier(S->getQualifier());
ID.AddBoolean(S->isArrow());
}
@@ -546,11 +547,6 @@
VisitType(S->getTypeAsWritten());
}
-void StmtProfiler::VisitCXXAdornedMemberExpr(CXXAdornedMemberExpr *S) {
- VisitMemberExpr(S);
- VisitNestedNameSpecifier(S->getQualifier());
-}
-
void StmtProfiler::VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *S) {
VisitExpr(S);
ID.AddBoolean(S->isArrow());
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 4390025..d0b6bbf 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -407,7 +407,6 @@
break;
case Stmt::MemberExprClass:
- case Stmt::CXXAdornedMemberExprClass:
VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst, false);
break;
@@ -514,7 +513,6 @@
return;
case Stmt::MemberExprClass:
- case Stmt::CXXAdornedMemberExprClass:
VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true);
return;
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 83f54b7..48326ee 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -241,7 +241,6 @@
case Expr::ExtVectorElementExprClass:
return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
case Expr::MemberExprClass:
- case Stmt::CXXAdornedMemberExprClass:
return EmitMemberExpr(cast<MemberExpr>(E));
case Expr::CompoundLiteralExprClass:
return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index cab807b..24eb8b1 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1456,8 +1456,7 @@
}
// Accesses to members are potential references to data on the stack.
- case Stmt::MemberExprClass:
- case Stmt::CXXAdornedMemberExprClass: {
+ case Stmt::MemberExprClass: {
MemberExpr *M = cast<MemberExpr>(E);
// Check for indirect access. We only want direct field accesses.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 7f680f5..df94f20 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -878,15 +878,14 @@
return false;
}
-/// \brief Build a MemberExpr or CXXAdornedMemberExpr, as appropriate.
+/// \brief Build a MemberExpr AST node.
static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
const CXXScopeSpec *SS, NamedDecl *Member,
SourceLocation Loc, QualType Ty) {
if (SS && SS->isSet())
- return new (C) CXXAdornedMemberExpr(Base, isArrow,
- (NestedNameSpecifier *)SS->getScopeRep(),
- SS->getRange(),
- Member, Loc, Ty);
+ return MemberExpr::Create(C, Base, isArrow,
+ (NestedNameSpecifier *)SS->getScopeRep(),
+ SS->getRange(), Member, Loc, Ty);
return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty);
}
@@ -4837,7 +4836,6 @@
case Stmt::QualifiedDeclRefExprClass:
return cast<DeclRefExpr>(E)->getDecl();
case Stmt::MemberExprClass:
- case Stmt::CXXAdornedMemberExprClass:
// If this is an arrow operator, the address is an offset from
// the base's value, so the object the base refers to is
// irrelevant.
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 8cb57d9..3879b39 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -835,13 +835,23 @@
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
- bool isArrow, SourceLocation MemberLoc,
+ bool isArrow,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ SourceLocation MemberLoc,
NamedDecl *Member) {
+ CXXScopeSpec SS;
+ if (Qualifier) {
+ SS.setRange(QualifierRange);
+ SS.setScopeRep(Qualifier);
+ }
+
return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
isArrow? tok::arrow : tok::period,
MemberLoc,
Member->getDeclName(),
- /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+ /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
+ &SS);
}
/// \brief Build a new binary operator expression.
@@ -1421,30 +1431,6 @@
RParenLoc);
}
- /// \brief Build a new qualified member access expression.
- ///
- /// By default, performs semantic analysis to build the new expression.
- /// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXAdornedMemberExpr(ExprArg Base,
- SourceLocation OpLoc,
- bool isArrow,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
- SourceLocation MemberLoc,
- NamedDecl *Member) {
- CXXScopeSpec SS;
- if (Qualifier) {
- SS.setRange(QualifierRange);
- SS.setScopeRep(Qualifier);
- }
- return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
- isArrow? tok::arrow : tok::period,
- MemberLoc,
- Member->getDeclName(),
- /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
- &SS);
- }
-
/// \brief Build a new member reference expression.
///
/// By default, performs semantic analysis to build the new expression.
@@ -2973,6 +2959,15 @@
if (Base.isInvalid())
return SemaRef.ExprError();
+ NestedNameSpecifier *Qualifier = 0;
+ if (E->hasQualifier()) {
+ Qualifier
+ = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
+ if (Qualifier == 0);
+ return SemaRef.ExprError();
+ }
+
NamedDecl *Member
= cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
if (!Member)
@@ -2980,6 +2975,7 @@
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase() &&
+ Qualifier == E->getQualifier() &&
Member == E->getMemberDecl())
return SemaRef.Owned(E->Retain());
@@ -2989,6 +2985,8 @@
return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
E->isArrow(),
+ Qualifier,
+ E->getQualifierRange(),
E->getMemberLoc(),
Member);
}
@@ -4016,45 +4014,7 @@
FakeCommaLocs.data(),
E->getRParenLoc());
}
-
-template<typename Derived>
-Sema::OwningExprResult
-TreeTransform<Derived>::TransformCXXAdornedMemberExpr(
- CXXAdornedMemberExpr *E) {
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
- if (Base.isInvalid())
- return SemaRef.ExprError();
-
- NamedDecl *Member
- = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
- if (!Member)
- return SemaRef.ExprError();
- NestedNameSpecifier *Qualifier
- = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
- if (Qualifier == 0 && E->getQualifier() != 0)
- return SemaRef.ExprError();
-
- if (!getDerived().AlwaysRebuild() &&
- Base.get() == E->getBase() &&
- Member == E->getMemberDecl() &&
- Qualifier == E->getQualifier())
- return SemaRef.Owned(E->Retain());
-
- // FIXME: Bogus source location for the operator
- SourceLocation FakeOperatorLoc
- = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
-
- return getDerived().RebuildCXXAdornedMemberExpr(move(Base),
- FakeOperatorLoc,
- E->isArrow(),
- Qualifier,
- E->getQualifierRange(),
- E->getMemberLoc(),
- Member);
-}
-
template<typename Derived>
Sema::OwningExprResult
TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(