From 26d4ac97fb514bb60c2536eae6f203dc569159d9 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 24 Feb 2010 23:40:28 +0000 Subject: [PATCH] Retain complete source information for the type after the '~' in a CXXPseudoDestructorExpr. Update template instantiation for pseudo-destructor expressions to use this source information and to make use of Sema::BuildPseudoDestructorExpr when the base expression is dependent or refers to a scalar type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97079 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 26 +++++----- lib/AST/ExprCXX.cpp | 7 +++ lib/Sema/SemaExpr.cpp | 6 ++- lib/Sema/SemaExprCXX.cpp | 19 ++++--- lib/Sema/TreeTransform.h | 99 +++++++++++++++++++++++++------------ 5 files changed, 98 insertions(+), 59 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index ccec7ef330..8f052f67aa 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1048,10 +1048,7 @@ class CXXPseudoDestructorExpr : public Expr { SourceLocation ColonColonLoc; /// \brief The type being destroyed. - QualType DestroyedType; - - /// \brief The location of the type after the '~'. - SourceLocation DestroyedTypeLoc; + TypeSourceInfo *DestroyedType; public: CXXPseudoDestructorExpr(ASTContext &Context, @@ -1060,20 +1057,20 @@ public: SourceRange QualifierRange, TypeSourceInfo *ScopeType, SourceLocation ColonColonLoc, - QualType DestroyedType, - SourceLocation DestroyedTypeLoc) + TypeSourceInfo *DestroyedType) : Expr(CXXPseudoDestructorExprClass, Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0, false, 0, false, false, 0, 0, false, CC_Default)), - /*isTypeDependent=*/false, + /*isTypeDependent=*/(Base->isTypeDependent() || + DestroyedType->getType()->isDependentType()), /*isValueDependent=*/Base->isValueDependent()), Base(static_cast(Base)), IsArrow(isArrow), OperatorLoc(OperatorLoc), Qualifier(Qualifier), QualifierRange(QualifierRange), ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), - DestroyedType(DestroyedType), DestroyedTypeLoc(DestroyedTypeLoc) { } + DestroyedType(DestroyedType) { } void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast(Base); } @@ -1110,21 +1107,20 @@ public: /// \p T may also be a scalar type and, therefore, cannot be part of a /// nested-name-specifier. It is stored as the "scope type" of the pseudo- /// destructor expression. - TypeSourceInfo *getScopeTypeLoc() const { return ScopeType; } + TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; } /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor /// expression. SourceLocation getColonColonLoc() const { return ColonColonLoc; } /// \brief Retrieve the type that is being destroyed. - QualType getDestroyedType() const { return DestroyedType; } + QualType getDestroyedType() const { return DestroyedType->getType(); } - /// \brief Retrieve the location of the type being destroyed. - SourceLocation getDestroyedTypeLoc() const { return DestroyedTypeLoc; } + /// \brief Retrieve the source location information for the type + /// being destroyed. + TypeSourceInfo *getDestroyedTypeInfo() const { return DestroyedType; } - virtual SourceRange getSourceRange() const { - return SourceRange(Base->getLocStart(), DestroyedTypeLoc); - } + virtual SourceRange getSourceRange() const; static bool classof(const Stmt *T) { return T->getStmtClass() == CXXPseudoDestructorExprClass; diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index f4b8333dd3..28d07f1df2 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/TypeLoc.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -121,6 +122,12 @@ Stmt::child_iterator CXXPseudoDestructorExpr::child_end() { return &Base + 1; } +SourceRange CXXPseudoDestructorExpr::getSourceRange() const { + return SourceRange(Base->getLocStart(), + DestroyedType->getTypeLoc().getSourceRange().getEnd()); +} + + // UnresolvedLookupExpr UnresolvedLookupExpr * UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent, diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5ced625f61..3fb587fc37 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2932,13 +2932,15 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, // FIXME: We've lost the precise spelling of the type by going through // DeclarationName. Can we do better? + TypeSourceInfo *DestroyedTypeInfo + = Context.getTrivialTypeSourceInfo(MemberName.getCXXNameType(), + MemberLoc); return Owned(new (Context) CXXPseudoDestructorExpr(Context, BaseExpr, IsArrow, OpLoc, (NestedNameSpecifier *) SS.getScopeRep(), SS.getRange(), 0, SourceLocation(), - MemberName.getCXXNameType(), - MemberLoc)); + DestroyedTypeInfo)); } // Handle access to Objective-C instance variables, such as "Obj->ivar" and diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index ef0ad6f8b1..98e8000b17 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2431,11 +2431,11 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base, SourceLocation OpLoc, tok::TokenKind OpKind, const CXXScopeSpec &SS, - TypeSourceInfo *ScopeTypeInfo, + TypeSourceInfo *ScopeTypeInfo, SourceLocation CCLoc, - TypeSourceInfo *DestructedTypeLoc, + TypeSourceInfo *DestructedTypeInfo, bool HasTrailingLParen) { - assert(DestructedTypeLoc && "No destructed type in pseudo-destructor expr?"); + assert(DestructedTypeInfo && "No destructed type in pseudo-destructor expr?"); // C++ [expr.pseudo]p2: // The left-hand side of the dot operator shall be of scalar type. The @@ -2467,18 +2467,18 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base, // C++ [expr.pseudo]p2: // [...] The cv-unqualified versions of the object type and of the type // designated by the pseudo-destructor-name shall be the same type. - QualType DestructedType = DestructedTypeLoc->getType(); + QualType DestructedType = DestructedTypeInfo->getType(); SourceLocation DestructedTypeStart - = DestructedTypeLoc->getTypeLoc().getSourceRange().getBegin(); + = DestructedTypeInfo->getTypeLoc().getSourceRange().getBegin(); if (!DestructedType->isDependentType() && !ObjectType->isDependentType() && !Context.hasSameUnqualifiedType(DestructedType, ObjectType)) { Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch) << ObjectType << DestructedType << BaseE->getSourceRange() - << DestructedTypeLoc->getTypeLoc().getSourceRange(); + << DestructedTypeInfo->getTypeLoc().getSourceRange(); // Recover by DestructedType = ObjectType; - DestructedTypeLoc = Context.getTrivialTypeSourceInfo(ObjectType, + DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart); } @@ -2513,13 +2513,12 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base, SS.getRange(), ScopeTypeInfo, CCLoc, - DestructedType, - DestructedTypeStart)); + DestructedTypeInfo)); if (HasTrailingLParen) return move(Result); return DiagnoseDtorReference( - DestructedTypeLoc->getTypeLoc().getSourceRange().getBegin(), + DestructedTypeInfo->getTypeLoc().getSourceRange().getBegin(), move(Result)); } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 40237d21d1..bd939f0aeb 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -884,28 +884,11 @@ public: OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base, SourceLocation OperatorLoc, bool isArrow, - SourceLocation DestroyedTypeLoc, - QualType DestroyedType, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange) { - CXXScopeSpec SS; - if (Qualifier) { - SS.setRange(QualifierRange); - SS.setScopeRep(Qualifier); - } - - QualType BaseType = ((Expr*) Base.get())->getType(); - - DeclarationName Name - = SemaRef.Context.DeclarationNames.getCXXDestructorName( - SemaRef.Context.getCanonicalType(DestroyedType)); - - return getSema().BuildMemberReferenceExpr(move(Base), BaseType, - OperatorLoc, isArrow, - SS, /*FIXME: FirstQualifier*/ 0, - Name, DestroyedTypeLoc, - /*TemplateArgs*/ 0); - } + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + TypeSourceInfo *ScopeType, + SourceLocation CCLoc, + TypeSourceInfo *DestroyedType); /// \brief Build a new unary operator expression. /// @@ -4694,27 +4677,35 @@ TreeTransform::TransformCXXPseudoDestructorExpr( if (E->getQualifier() && !Qualifier) return SemaRef.ExprError(); - QualType DestroyedType; - { - TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName()); - DestroyedType = getDerived().TransformType(E->getDestroyedType()); - if (DestroyedType.isNull()) + // FIXME: Object type! + TypeSourceInfo *DestroyedTypeInfo + = getDerived().TransformType(E->getDestroyedTypeInfo()); + if (!DestroyedTypeInfo) + return SemaRef.ExprError(); + + // FIXME: Object type! + TypeSourceInfo *ScopeTypeInfo = 0; + if (E->getScopeTypeInfo()) { + ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo()); + if (!ScopeTypeInfo) return SemaRef.ExprError(); } - + if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && Qualifier == E->getQualifier() && - DestroyedType == E->getDestroyedType()) + ScopeTypeInfo == E->getScopeTypeInfo() && + DestroyedTypeInfo == E->getDestroyedTypeInfo()) return SemaRef.Owned(E->Retain()); return getDerived().RebuildCXXPseudoDestructorExpr(move(Base), E->getOperatorLoc(), E->isArrow(), - E->getDestroyedTypeLoc(), - DestroyedType, Qualifier, - E->getQualifierRange()); + E->getQualifierRange(), + ScopeTypeInfo, + E->getColonColonLoc(), + DestroyedTypeInfo); } template @@ -5755,6 +5746,50 @@ TreeTransform::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, return move(Result); } +template +Sema::OwningExprResult +TreeTransform::RebuildCXXPseudoDestructorExpr(ExprArg Base, + SourceLocation OperatorLoc, + bool isArrow, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + TypeSourceInfo *ScopeType, + SourceLocation CCLoc, + TypeSourceInfo *DestroyedType) { + CXXScopeSpec SS; + if (Qualifier) { + SS.setRange(QualifierRange); + SS.setScopeRep(Qualifier); + } + + Expr *BaseE = (Expr *)Base.get(); + QualType BaseType = BaseE->getType(); + if (BaseE->isTypeDependent() || + (!isArrow && !BaseType->getAs()) || + (isArrow && BaseType->getAs() && + !BaseType->getAs()->getAs())) { + // This pseudo-destructor expression is still a pseudo-destructor. + return SemaRef.BuildPseudoDestructorExpr(move(Base), OperatorLoc, + isArrow? tok::arrow : tok::period, + SS, ScopeType, CCLoc, + DestroyedType, + /*FIXME?*/true); + } + + DeclarationName Name + = SemaRef.Context.DeclarationNames.getCXXDestructorName( + SemaRef.Context.getCanonicalType(DestroyedType->getType())); + + // FIXME: the ScopeType should be tacked onto SS. + + return getSema().BuildMemberReferenceExpr(move(Base), BaseType, + OperatorLoc, isArrow, + SS, /*FIXME: FirstQualifier*/ 0, + Name, + DestroyedType->getTypeLoc().getSourceRange().getBegin(), + /*TemplateArgs*/ 0); +} + } // end namespace clang #endif // LLVM_CLANG_SEMA_TREETRANSFORM_H