From: Douglas Gregor Date: Mon, 31 Aug 2009 21:41:48 +0000 (+0000) Subject: Rename CXXQualifiedMemberExpr -> CXXAdornedMemberExpr, since we will X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0979c805475d1ba49b5d6ef93c4d2ce6d2eab6ed;p=clang Rename CXXQualifiedMemberExpr -> CXXAdornedMemberExpr, since we will also be adding explicit template arguments as an additional "adornment". No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80628 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 809473bc41..f5048edc34 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -33,7 +33,7 @@ namespace clang { class BlockDecl; class CXXOperatorCallExpr; class CXXMemberCallExpr; - class CXXQualifiedMemberExpr; + class CXXAdornedMemberExpr; /// Expr - This represents one expression. Note that Expr's are subclasses of /// Stmt. This allows an expression to be transparently used any place a Stmt @@ -1078,6 +1078,11 @@ public: NamedDecl *getMemberDecl() const { return MemberDecl; } void setMemberDecl(NamedDecl *D) { MemberDecl = D; } + /// \brief Determines whether this adorned member expression actually had + /// a C++ nested-name-specifier prior to the name of the member, e.g., + /// x->Base::foo. + bool hasQualifier() const; + bool isArrow() const { return IsArrow; } void setArrow(bool A) { IsArrow = A; } @@ -1099,10 +1104,10 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass || - T->getStmtClass() == CXXQualifiedMemberExprClass; + T->getStmtClass() == CXXAdornedMemberExprClass; } static bool classof(const MemberExpr *) { return true; } - static bool classof(const CXXQualifiedMemberExpr *) { return true; } + static bool classof(const CXXAdornedMemberExpr *) { return true; } // Iterators virtual child_iterator child_begin(); diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 7e21a73cc2..626cbd155b 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1286,8 +1286,9 @@ public: }; /// \brief Represents a C++ member access expression that was written using -/// a qualified name, e.g., "x->Base::f()". -class CXXQualifiedMemberExpr : public MemberExpr { +/// either a qualified name, e.g., "x->Base::f()" or originally had +/// explicitly-specified template arguments (TODO!). +class CXXAdornedMemberExpr : public MemberExpr { /// QualifierRange - The source range that covers the /// nested-name-specifier. SourceRange QualifierRange; @@ -1297,10 +1298,10 @@ class CXXQualifiedMemberExpr : public MemberExpr { NestedNameSpecifier *Qualifier; public: - CXXQualifiedMemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *Qual, - SourceRange QualRange, NamedDecl *memberdecl, - SourceLocation l, QualType ty) - : MemberExpr(CXXQualifiedMemberExprClass, base, isarrow, memberdecl, l, ty), + CXXAdornedMemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *Qual, + SourceRange QualRange, NamedDecl *memberdecl, + SourceLocation l, QualType ty) + : MemberExpr(CXXAdornedMemberExprClass, base, isarrow, memberdecl, l, ty), QualifierRange(QualRange), Qualifier(Qual) { } /// \brief Retrieve the source range of the nested-name-specifier that @@ -1311,10 +1312,14 @@ public: /// member reference expression. NestedNameSpecifier *getQualifier() const { return Qualifier; } + /// \brief Determines whether this adorned C++ member expression has a + /// nested-name-specifier associated with it. + bool hasQualifier() const { return getQualifier() != 0; } + static bool classof(const Stmt *T) { - return T->getStmtClass() == CXXQualifiedMemberExprClass; + return T->getStmtClass() == CXXAdornedMemberExprClass; } - static bool classof(const CXXQualifiedMemberExpr *) { return true; } + static bool classof(const CXXAdornedMemberExpr *) { return true; } }; /// \brief Represents a C++ member access expression where the actual member diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def index 72dfa612c0..35f2815059 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -134,7 +134,7 @@ EXPR(CXXBindTemporaryExpr , Expr) EXPR(CXXExprWithTemporaries , Expr) EXPR(CXXTemporaryObjectExpr , CXXConstructExpr) EXPR(CXXUnresolvedConstructExpr, Expr) -EXPR(CXXQualifiedMemberExpr, MemberExpr) +EXPR(CXXAdornedMemberExpr, MemberExpr) EXPR(CXXUnresolvedMemberExpr, Expr) // Obj-C Expressions. diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index c890812d91..6bc4854628 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" @@ -497,7 +498,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, } case MemberExprClass: - case CXXQualifiedMemberExprClass: + case CXXAdornedMemberExprClass: // If the base pointer or element is to a volatile pointer/field, accessing // it is a side effect. if (getType().isVolatileQualified()) @@ -686,7 +687,7 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const { break; } case MemberExprClass: - case CXXQualifiedMemberExprClass: { + case CXXAdornedMemberExprClass: { const MemberExpr *m = cast(this); if (Ctx.getLangOptions().CPlusPlus) { // C++ [expr.ref]p4: NamedDecl *Member = m->getMemberDecl(); @@ -958,7 +959,7 @@ bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const { return false; } case MemberExprClass: - case CXXQualifiedMemberExprClass: { + case CXXAdornedMemberExprClass: { const MemberExpr *M = cast(this); return M->getBase()->isOBJCGCCandidate(Ctx); } @@ -1916,6 +1917,13 @@ Stmt::child_iterator CallExpr::child_end() { 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(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 c9614e178c..d09358c08a 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1126,7 +1126,7 @@ StmtPrinter::VisitCXXUnresolvedConstructExpr( OS << ")"; } -void StmtPrinter::VisitCXXQualifiedMemberExpr(CXXQualifiedMemberExpr *Node) { +void StmtPrinter::VisitCXXAdornedMemberExpr(CXXAdornedMemberExpr *Node) { // FIXME: Suppress printing implicit bases (like "this") PrintExpr(Node->getBase()); OS << (Node->isArrow() ? "->" : "."); diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 0ffe5e17c6..8ce620c625 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -546,7 +546,7 @@ StmtProfiler::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *S) { VisitType(S->getTypeAsWritten()); } -void StmtProfiler::VisitCXXQualifiedMemberExpr(CXXQualifiedMemberExpr *S) { +void StmtProfiler::VisitCXXAdornedMemberExpr(CXXAdornedMemberExpr *S) { VisitMemberExpr(S); VisitNestedNameSpecifier(S->getQualifier()); } diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index d66dfffd31..4390025f58 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -407,7 +407,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) { break; case Stmt::MemberExprClass: - case Stmt::CXXQualifiedMemberExprClass: + case Stmt::CXXAdornedMemberExprClass: VisitMemberExpr(cast(S), Pred, Dst, false); break; @@ -514,7 +514,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred, return; case Stmt::MemberExprClass: - case Stmt::CXXQualifiedMemberExprClass: + case Stmt::CXXAdornedMemberExprClass: VisitMemberExpr(cast(Ex), Pred, Dst, true); return; diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 4ca0473312..cb12ac948c 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -216,9 +216,9 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { // Explicit qualification with the scope operator (5.1) suppresses the // virtual call mechanism. llvm::Value *Callee; - if (MD->isVirtual() && !isa(ME)) { + if (MD->isVirtual() && !ME->hasQualifier()) Callee = BuildVirtualCall(MD, This, Ty); - } else + else Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); return EmitCXXMemberCall(MD, Callee, This, diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 400d45ffe5..83f54b76eb 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -241,7 +241,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::ExtVectorElementExprClass: return EmitExtVectorElementExpr(cast(E)); case Expr::MemberExprClass: - case Stmt::CXXQualifiedMemberExprClass: + case Stmt::CXXAdornedMemberExprClass: return EmitMemberExpr(cast(E)); case Expr::CompoundLiteralExprClass: return EmitCompoundLiteralLValue(cast(E)); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 449c5f3384..cab807b999 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -1457,7 +1457,7 @@ static DeclRefExpr* EvalVal(Expr *E) { // Accesses to members are potential references to data on the stack. case Stmt::MemberExprClass: - case Stmt::CXXQualifiedMemberExprClass: { + case Stmt::CXXAdornedMemberExprClass: { MemberExpr *M = cast(E); // Check for indirect access. We only want direct field accesses. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 026ff43d2d..7f680f5d2f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -878,15 +878,15 @@ Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) { return false; } -/// \brief Build a MemberExpr or CXXQualifiedMemberExpr, as appropriate. +/// \brief Build a MemberExpr or CXXAdornedMemberExpr, as appropriate. 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) CXXQualifiedMemberExpr(Base, isArrow, - (NestedNameSpecifier *)SS->getScopeRep(), - SS->getRange(), - Member, Loc, Ty); + return new (C) CXXAdornedMemberExpr(Base, isArrow, + (NestedNameSpecifier *)SS->getScopeRep(), + SS->getRange(), + Member, Loc, Ty); return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty); } @@ -4837,7 +4837,7 @@ static NamedDecl *getPrimaryDecl(Expr *E) { case Stmt::QualifiedDeclRefExprClass: return cast(E)->getDecl(); case Stmt::MemberExprClass: - case Stmt::CXXQualifiedMemberExprClass: + 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 deb54115a5..8cb57d904f 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1425,16 +1425,18 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - OwningExprResult RebuildCXXQualifiedMemberExpr(ExprArg Base, - SourceLocation OpLoc, - bool isArrow, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - SourceLocation MemberLoc, - NamedDecl *Member) { + OwningExprResult RebuildCXXAdornedMemberExpr(ExprArg Base, + SourceLocation OpLoc, + bool isArrow, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + SourceLocation MemberLoc, + NamedDecl *Member) { CXXScopeSpec SS; - SS.setRange(QualifierRange); - SS.setScopeRep(Qualifier); + if (Qualifier) { + SS.setRange(QualifierRange); + SS.setScopeRep(Qualifier); + } return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc, isArrow? tok::arrow : tok::period, MemberLoc, @@ -1588,6 +1590,9 @@ template NestedNameSpecifier * TreeTransform::TransformNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range) { + if (!NNS) + return 0; + // Transform the prefix of this nested name specifier. NestedNameSpecifier *Prefix = NNS->getPrefix(); if (Prefix) { @@ -4014,8 +4019,8 @@ TreeTransform::TransformCXXUnresolvedConstructExpr( template Sema::OwningExprResult -TreeTransform::TransformCXXQualifiedMemberExpr( - CXXQualifiedMemberExpr *E) { +TreeTransform::TransformCXXAdornedMemberExpr( + CXXAdornedMemberExpr *E) { OwningExprResult Base = getDerived().TransformExpr(E->getBase()); if (Base.isInvalid()) return SemaRef.ExprError(); @@ -4028,7 +4033,7 @@ TreeTransform::TransformCXXQualifiedMemberExpr( NestedNameSpecifier *Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(), E->getQualifierRange()); - if (Qualifier == 0) + if (Qualifier == 0 && E->getQualifier() != 0) return SemaRef.ExprError(); if (!getDerived().AlwaysRebuild() && @@ -4041,7 +4046,7 @@ TreeTransform::TransformCXXQualifiedMemberExpr( SourceLocation FakeOperatorLoc = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd()); - return getDerived().RebuildCXXQualifiedMemberExpr(move(Base), + return getDerived().RebuildCXXAdornedMemberExpr(move(Base), FakeOperatorLoc, E->isArrow(), Qualifier,