diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-02-24 21:52:20 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-02-24 21:52:20 +0000 |
commit | 75d8ec1fbe4a8649580e7ad1a889ecb3f3277608 (patch) | |
tree | de104f03cc107089b1f496d53da2bdf2d2bf2317 /clang | |
parent | 9b7cfd39b270111cc015b26fbbc889d77f589a6f (diff) | |
download | bcm5719-llvm-75d8ec1fbe4a8649580e7ad1a889ecb3f3277608.tar.gz bcm5719-llvm-75d8ec1fbe4a8649580e7ad1a889ecb3f3277608.zip |
Retain source information for the "type-name ::" in a
pseudo-destructor expression such as
p->T::~T()
llvm-svn: 97060
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 51 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 9 |
3 files changed, 50 insertions, 11 deletions
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 0861ff1b764..ccec7ef3301 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -999,19 +999,28 @@ public: /// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]). /// -/// Example: +/// A pseudo-destructor is an expression that looks like a member access to a +/// destructor of a scalar type, except that scalar types don't have +/// destructors. For example: +/// +/// \code +/// typedef int T; +/// void f(int *p) { +/// p->T::~T(); +/// } +/// \endcode /// +/// Pseudo-destructors typically occur when instantiating templates such as: +/// /// \code /// template<typename T> /// void destroy(T* ptr) { -/// ptr->~T(); +/// ptr->T::~T(); /// } /// \endcode /// -/// When the template is parsed, the expression \c ptr->~T will be stored as -/// a member reference expression. If it then instantiated with a scalar type -/// as a template argument for T, the resulting expression will be a -/// pseudo-destructor expression. +/// for scalar types. A pseudo-destructor expression has no run-time semantics +/// beyond evaluating the base expression. class CXXPseudoDestructorExpr : public Expr { /// \brief The base expression (that is being destroyed). Stmt *Base; @@ -1030,6 +1039,14 @@ class CXXPseudoDestructorExpr : public Expr { /// present. SourceRange QualifierRange; + /// \brief The type that precedes the '::' in a qualified pseudo-destructor + /// expression. + TypeSourceInfo *ScopeType; + + /// \brief The location of the '::' in a qualified pseudo-destructor + /// expression. + SourceLocation ColonColonLoc; + /// \brief The type being destroyed. QualType DestroyedType; @@ -1041,6 +1058,8 @@ public: Expr *Base, bool isArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, + TypeSourceInfo *ScopeType, + SourceLocation ColonColonLoc, QualType DestroyedType, SourceLocation DestroyedTypeLoc) : Expr(CXXPseudoDestructorExprClass, @@ -1052,8 +1071,9 @@ public: /*isValueDependent=*/Base->isValueDependent()), Base(static_cast<Stmt *>(Base)), IsArrow(isArrow), OperatorLoc(OperatorLoc), Qualifier(Qualifier), - QualifierRange(QualifierRange), DestroyedType(DestroyedType), - DestroyedTypeLoc(DestroyedTypeLoc) { } + QualifierRange(QualifierRange), + ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), + DestroyedType(DestroyedType), DestroyedTypeLoc(DestroyedTypeLoc) { } void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast<Expr>(Base); } @@ -1081,6 +1101,21 @@ public: /// \brief Retrieve the location of the '.' or '->' operator. SourceLocation getOperatorLoc() const { return OperatorLoc; } + /// \brief Retrieve the scope type in a qualified pseudo-destructor + /// expression. + /// + /// Pseudo-destructor expressions can have extra qualification within them + /// that is not part of the nested-name-specifier, e.g., \c p->T::~T(). + /// Here, if the object type of the expression is (or may be) a scalar type, + /// \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; } + + /// \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; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c3116a3885e..5ced625f61c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2936,6 +2936,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, IsArrow, OpLoc, (NestedNameSpecifier *) SS.getScopeRep(), SS.getRange(), + 0, SourceLocation(), MemberName.getCXXNameType(), MemberLoc)); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 9172956b515..53b3ab070fe 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2664,7 +2664,8 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base, // // ::[opt] nested-name-specifier[opt] type-name :: ~ type-name // - // shall designate the same scalar type. + // shall designate the same scalar type. + TypeSourceInfo *ScopeTypeLoc; QualType ScopeType; if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId || FirstTypeName.Identifier) { @@ -2680,7 +2681,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base, return ExprError(); } else { // FIXME: Drops source-location information. - ScopeType = GetTypeFromParser(T); + ScopeType = GetTypeFromParser(T, &ScopeTypeLoc); if (!ScopeType->isDependentType() && !Context.hasSameUnqualifiedType(DestructedType, ScopeType)) { @@ -2690,6 +2691,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base, << ObjectType << ScopeType << BaseE->getSourceRange(); ScopeType = QualType(); + ScopeTypeLoc = 0; } } } else { @@ -2707,7 +2709,6 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base, } } - // FIXME: Drops the scope type. OwningExprResult Result = Owned(new (Context) CXXPseudoDestructorExpr(Context, Base.takeAs<Expr>(), @@ -2715,6 +2716,8 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base, OpLoc, (NestedNameSpecifier *) SS.getScopeRep(), SS.getRange(), + ScopeTypeLoc, + CCLoc, DestructedType, SecondTypeName.StartLocation)); if (HasTrailingLParen) |