Implement AST, semantics, and CodeGen for C++ pseudo-destructor
expressions, e.g.,

  p->~T()

when p is a pointer to a scalar type. 

We don't currently diagnose errors when pseudo-destructor expressions
are used in any way other than by forming a call.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81009 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 2faaa44..22e01ab 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -783,6 +783,36 @@
     return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
   }
 
+  /// \brief Build a new pseudo-destructor expression.
+  /// 
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  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);
+    }
+
+    DeclarationName Name 
+      = SemaRef.Context.DeclarationNames.getCXXDestructorName(
+                               SemaRef.Context.getCanonicalType(DestroyedType));
+    
+    return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), 
+                                              OperatorLoc,
+                                              isArrow? tok::arrow : tok::period,
+                                              DestroyedTypeLoc,
+                                              Name,
+                                              Sema::DeclPtrTy::make((Decl *)0),
+                                              &SS);
+  }                                              
+  
   /// \brief Build a new unary operator expression.
   /// 
   /// By default, performs semantic analysis to build the new expression.
@@ -3814,6 +3844,43 @@
   
 template<typename Derived>
 Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
+                                                CXXPseudoDestructorExpr *E) {
+  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+  
+  NestedNameSpecifier *Qualifier
+    = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+                                                E->getQualifierRange());
+  if (E->getQualifier() && !Qualifier)
+    return SemaRef.ExprError();
+  
+  QualType DestroyedType;
+  {
+    TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
+    DestroyedType = getDerived().TransformType(E->getDestroyedType());
+    if (DestroyedType.isNull())
+      return SemaRef.ExprError();
+  }
+  
+  if (!getDerived().AlwaysRebuild() &&
+      Base.get() == E->getBase() &&
+      Qualifier == E->getQualifier() &&
+      DestroyedType == E->getDestroyedType())
+    return SemaRef.Owned(E->Retain());
+  
+  return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
+                                                     E->getOperatorLoc(),
+                                                     E->isArrow(),
+                                                     E->getDestroyedTypeLoc(),
+                                                     DestroyedType,
+                                                     Qualifier,
+                                                     E->getQualifierRange());
+}
+    
+template<typename Derived>
+Sema::OwningExprResult
 TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
                                               UnresolvedFunctionNameExpr *E) { 
   // There is no transformation we can apply to an unresolved function name.