From 83233a4b7c2bc7b531ffa3b33fdd1cd8138373b6 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 7 Jan 2009 21:26:07 +0000 Subject: [PATCH] Fix printing of member references to avoid displaying implicitly-generated member references, e.g., for anonymous struct/unions or implicit 'this' in member functions git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61885 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Expr.h | 26 ++++++++++++++++++++------ lib/AST/StmtPrinter.cpp | 6 ++++-- lib/Sema/SemaExpr.cpp | 4 ++++ lib/Sema/SemaInit.cpp | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 0490aab200..812b5ca642 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -49,15 +49,21 @@ class Expr : public Stmt { /// (C++ [temp.dep.constexpr]). bool ValueDependent : 1; + /// Implicit - Whether this expression was implicitly created by the + /// implementation, rather than written explicitly by the user. + bool Implicit : 1; + protected: // FIXME: Eventually, this constructor should go away and we should // require every subclass to provide type/value-dependence // information. Expr(StmtClass SC, QualType T) - : Stmt(SC), TypeDependent(false), ValueDependent(false) { setType(T); } + : Stmt(SC), TypeDependent(false), ValueDependent(false), Implicit(false) { + setType(T); + } Expr(StmtClass SC, QualType T, bool TD, bool VD) - : Stmt(SC), TypeDependent(TD), ValueDependent(VD) { + : Stmt(SC), TypeDependent(TD), ValueDependent(VD), Implicit(false) { setType(T); } @@ -99,6 +105,14 @@ public: /// @endcode bool isTypeDependent() const { return TypeDependent; } + /// isImplicit - Determines whether this expression was implicitly + /// created by the implementation to express the semantics of an + /// implicit operation, such as an implicit conversion or implicit + /// reference to "this". When false, this expression was written + /// directly in the source code. + bool isImplicit() const { return Implicit; } + void setImplicit(bool I = true) { Implicit = I; } + /// SourceLocation tokens are not useful in isolation - they are low level /// value objects created/interpreted by SourceManager. We assume AST /// clients will have a pointer to the respective SourceManager. @@ -982,7 +996,9 @@ class ImplicitCastExpr : public CastExpr { public: ImplicitCastExpr(QualType ty, Expr *op, bool Lvalue) : - CastExpr(ImplicitCastExprClass, ty, op), LvalueCast(Lvalue) {} + CastExpr(ImplicitCastExprClass, ty, op), LvalueCast(Lvalue) { + setImplicit(true); + } virtual SourceRange getSourceRange() const { return getSubExpr()->getSourceRange(); @@ -1671,9 +1687,7 @@ public: // Explicit InitListExpr's originate from source code (and have valid source // locations). Implicit InitListExpr's are created by the semantic analyzer. - bool isExplicit() { - return LBraceLoc.isValid() && RBraceLoc.isValid(); - } + bool isExplicit() { return !isImplicit(); } virtual SourceRange getSourceRange() const { return SourceRange(LBraceLoc, RBraceLoc); diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 679c897497..7456e8cca9 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -757,8 +757,10 @@ void StmtPrinter::VisitCallExpr(CallExpr *Call) { OS << ")"; } void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { - PrintExpr(Node->getBase()); - OS << (Node->isArrow() ? "->" : "."); + if (!Node->getBase()->isImplicit()) { + PrintExpr(Node->getBase()); + OS << (Node->isArrow() ? "->" : "."); + } OS << Node->getMemberDecl()->getNameAsString(); } void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bf04042ef8..6db6ea19af 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -444,6 +444,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, BaseObjectExpr = new DeclRefExpr(BaseObject, BaseObject->getType(), SourceLocation()); + BaseObjectExpr->setImplicit(); ExtraQuals = Context.getCanonicalType(BaseObject->getType()).getCVRQualifiers(); } else if (BaseObjectExpr) { @@ -473,6 +474,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, BaseObjectExpr = new CXXThisExpr(SourceLocation(), MD->getThisType(Context)); BaseObjectIsPointer = true; + BaseObjectExpr->setImplicit(); } } else { return Diag(Loc, diag::err_invalid_member_use_in_static_method) @@ -500,6 +502,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, } Result = new MemberExpr(Result, BaseObjectIsPointer, *FI, OpLoc, MemberType); + Result->setImplicit(); BaseObjectIsPointer = false; ExtraQuals = Context.getCanonicalType(MemberType).getCVRQualifiers(); OpLoc = SourceLocation(); @@ -661,6 +664,7 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // Build the implicit member access expression. Expr *This = new CXXThisExpr(SourceLocation(), MD->getThisType(Context)); + This->setImplicit(); return new MemberExpr(This, true, cast(D), SourceLocation(), MemberType); } diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 031fe27ddf..6a9275fbe8 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -90,6 +90,7 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList, &InitExprs[0], InitExprs.size(), SourceLocation(), ParentIList->hadDesignators()); + ILE->setImplicit(); ILE->setType(T); // Modify the parent InitListExpr to point to the implicit InitListExpr. -- 2.40.0