[cfe-commits] r97060 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 24 13:52:20 PST 2010
Author: dgregor
Date: Wed Feb 24 15:52:20 2010
New Revision: 97060
URL: http://llvm.org/viewvc/llvm-project?rev=97060&view=rev
Log:
Retain source information for the "type-name ::" in a
pseudo-destructor expression such as
p->T::~T()
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=97060&r1=97059&r2=97060&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Feb 24 15:52:20 2010
@@ -999,19 +999,28 @@
/// \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 @@
/// 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 @@
Expr *Base, bool isArrow, SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
+ TypeSourceInfo *ScopeType,
+ SourceLocation ColonColonLoc,
QualType DestroyedType,
SourceLocation DestroyedTypeLoc)
: Expr(CXXPseudoDestructorExprClass,
@@ -1052,8 +1071,9 @@
/*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 @@
/// \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; }
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=97060&r1=97059&r2=97060&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Feb 24 15:52:20 2010
@@ -2936,6 +2936,7 @@
IsArrow, OpLoc,
(NestedNameSpecifier *) SS.getScopeRep(),
SS.getRange(),
+ 0, SourceLocation(),
MemberName.getCXXNameType(),
MemberLoc));
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=97060&r1=97059&r2=97060&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Feb 24 15:52:20 2010
@@ -2664,7 +2664,8 @@
//
// ::[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 @@
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 @@
<< ObjectType << ScopeType << BaseE->getSourceRange();
ScopeType = QualType();
+ ScopeTypeLoc = 0;
}
}
} else {
@@ -2707,7 +2709,6 @@
}
}
- // FIXME: Drops the scope type.
OwningExprResult Result
= Owned(new (Context) CXXPseudoDestructorExpr(Context,
Base.takeAs<Expr>(),
@@ -2715,6 +2716,8 @@
OpLoc,
(NestedNameSpecifier *) SS.getScopeRep(),
SS.getRange(),
+ ScopeTypeLoc,
+ CCLoc,
DestructedType,
SecondTypeName.StartLocation));
if (HasTrailingLParen)
More information about the cfe-commits
mailing list