[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