Retain complete source-location information for C++
nested-name-specifiers throughout the parser, and provide a new class
(NestedNameSpecifierLoc) that contains a nested-name-specifier along
with its type-source information.

Right now, this information is completely useless, because we don't
actually store the source-location information anywhere in the
AST. Call this Step 1/N.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126391 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index f21d90f..2d85374 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -14,6 +14,7 @@
 #include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ParsedTemplate.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Lex/Preprocessor.h"
@@ -46,6 +47,85 @@
   EndLocation = TemplateId->RAngleLoc;
 }
 
+CXXScopeSpec::CXXScopeSpec(const CXXScopeSpec &Other)
+  : Range(Other.Range), ScopeRep(Other.ScopeRep), Buffer(0), 
+    BufferSize(Other.BufferSize), BufferCapacity(Other.BufferSize) 
+{
+  if (BufferSize) {
+    Buffer = static_cast<char *>(malloc(BufferSize));
+    memcpy(Buffer, Other.Buffer, BufferSize);
+  }
+}
+
+CXXScopeSpec &CXXScopeSpec::operator=(const CXXScopeSpec &Other) {
+  Range = Other.Range;
+  ScopeRep = Other.ScopeRep;
+  if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
+    // Re-use our storage.
+    BufferSize = Other.BufferSize;
+    memcpy(Buffer, Other.Buffer, BufferSize);
+    return *this;
+  }
+  
+  if (BufferCapacity)
+    free(Buffer);
+  if (Other.Buffer) {
+    BufferSize = Other.BufferSize;
+    BufferCapacity = BufferSize;
+    Buffer = static_cast<char *>(malloc(BufferSize));
+    memcpy(Buffer, Other.Buffer, BufferSize);
+  } else {
+    Buffer = 0;
+    BufferSize = 0;
+    BufferCapacity = 0;
+  }
+  return *this;
+}
+
+CXXScopeSpec::~CXXScopeSpec() {
+  if (BufferCapacity)
+    free(Buffer);
+}
+
+namespace {
+  void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
+              unsigned &BufferCapacity) {
+    if (BufferSize + (End - Start) > BufferCapacity) {
+      // Reallocate the buffer.
+      unsigned NewCapacity 
+        = std::max((unsigned)(BufferCapacity? BufferCapacity * 2 
+                                            : sizeof(void*) * 2),
+                   (unsigned)(BufferSize + (End - Start)));
+      char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
+      memcpy(NewBuffer, Buffer, BufferSize);
+      
+      if (BufferCapacity)
+        free(Buffer);
+      Buffer = NewBuffer;
+      BufferCapacity = NewCapacity;
+    }
+    
+    memcpy(Buffer + BufferSize, Start, End - Start);
+    BufferSize += End-Start;
+  }
+  
+  /// \brief Save a source location to the given buffer.
+  void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
+                          unsigned &BufferSize, unsigned &BufferCapacity) {
+    unsigned Raw = Loc.getRawEncoding();
+    Append(reinterpret_cast<char *>(&Raw),
+           reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
+           Buffer, BufferSize, BufferCapacity);
+  }
+  
+  /// \brief Save a pointer to the given buffer.
+  void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
+                   unsigned &BufferCapacity) {
+    Append(reinterpret_cast<char *>(&Ptr),
+           reinterpret_cast<char *>(&Ptr) + sizeof(void *),
+           Buffer, BufferSize, BufferCapacity);
+  }
+}
 void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 
                           TypeLoc TL, SourceLocation ColonColonLoc) {
   ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, 
@@ -54,6 +134,13 @@
   if (Range.getBegin().isInvalid())
     Range.setBegin(TL.getBeginLoc());
   Range.setEnd(ColonColonLoc);
+
+  // Push source-location info into the buffer.
+  SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
+  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+
+  assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+         "NestedNameSpecifierLoc range computation incorrect");
 }
 
 void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
@@ -63,6 +150,13 @@
   if (Range.getBegin().isInvalid())
     Range.setBegin(IdentifierLoc);
   Range.setEnd(ColonColonLoc);
+  
+  // Push source-location info into the buffer.
+  SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
+  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+  
+  assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+         "NestedNameSpecifierLoc range computation incorrect");
 }
 
 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
@@ -72,6 +166,13 @@
   if (Range.getBegin().isInvalid())
     Range.setBegin(NamespaceLoc);
   Range.setEnd(ColonColonLoc);
+
+  // Push source-location info into the buffer.
+  SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
+  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+  
+  assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+         "NestedNameSpecifierLoc range computation incorrect");
 }
 
 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
@@ -81,6 +182,13 @@
   if (Range.getBegin().isInvalid())
     Range.setBegin(AliasLoc);
   Range.setEnd(ColonColonLoc);
+
+  // Push source-location info into the buffer.
+  SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
+  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+  
+  assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+         "NestedNameSpecifierLoc range computation incorrect");
 }
 
 void CXXScopeSpec::MakeGlobal(ASTContext &Context, 
@@ -88,6 +196,87 @@
   assert(!ScopeRep && "Already have a nested-name-specifier!?");
   ScopeRep = NestedNameSpecifier::GlobalSpecifier(Context);
   Range = SourceRange(ColonColonLoc);
+  
+  // Push source-location info into the buffer.
+  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+  
+  assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+         "NestedNameSpecifierLoc range computation incorrect");
+}
+
+void CXXScopeSpec::MakeTrivial(ASTContext &Context, 
+                               NestedNameSpecifier *Qualifier, SourceRange R) {
+  ScopeRep = Qualifier;
+  Range = R;
+
+  // Construct bogus (but well-formed) source information for the 
+  // nested-name-specifier.
+  BufferSize = 0;
+  llvm::SmallVector<NestedNameSpecifier *, 4> Stack;
+  for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
+    Stack.push_back(NNS);
+  while (!Stack.empty()) {
+    NestedNameSpecifier *NNS = Stack.back();
+    Stack.pop_back();
+    switch (NNS->getKind()) {
+    case NestedNameSpecifier::Identifier:
+    case NestedNameSpecifier::Namespace:
+    case NestedNameSpecifier::NamespaceAlias:
+      SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
+      break;
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate: {
+      TypeSourceInfo *TSInfo
+        = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
+                                           R.getBegin());
+      SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize, 
+                  BufferCapacity);
+      break;
+    }
+        
+    case NestedNameSpecifier::Global:
+      break;
+    }
+
+    // Save the location of the '::'.
+    SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(), 
+                       Buffer, BufferSize, BufferCapacity);
+  }
+}
+
+void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
+  if (!Other) {
+    Range = SourceRange();
+    ScopeRep = 0;
+    return;
+  }
+    
+  if (BufferCapacity)
+    free(Buffer);
+  
+  // Rather than copying the data (which is wasteful), "adopt" the 
+  // pointer (which points into the ASTContext) but set the capacity to zero to
+  // indicate that we don't own it.
+  Range = Other.getSourceRange();
+  ScopeRep = Other.getNestedNameSpecifier();
+  Buffer = static_cast<char *>(Other.getOpaqueData());
+  BufferSize = Other.getDataLength();
+  BufferCapacity = 0;
+}
+
+NestedNameSpecifierLoc CXXScopeSpec::getWithLocInContext(ASTContext &Context) {
+  if (isEmpty() || isInvalid())
+    return NestedNameSpecifierLoc();
+  
+  // If we adopted our data pointer from elsewhere in the AST context, there's
+  // no need to copy the memory.
+  if (BufferCapacity == 0)
+    return NestedNameSpecifierLoc(ScopeRep, Buffer);
+  
+  void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
+  memcpy(Mem, Buffer, BufferSize);
+  return NestedNameSpecifierLoc(ScopeRep, Mem);
 }
 
 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 9daec58..7ad4b45 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -658,6 +658,41 @@
   return false;
 }
 
+namespace {
+  /// \brief A structure that stores a nested-name-specifier annotation,
+  /// including both the nested-name-specifier 
+  struct NestedNameSpecifierAnnotation {
+    NestedNameSpecifier *NNS;
+  };
+}
+
+void *Sema::SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS) {
+  if (SS.isEmpty() || SS.isInvalid())
+    return 0;
+  
+  void *Mem = Context.Allocate((sizeof(NestedNameSpecifierAnnotation) +
+                                                        SS.location_size()),
+                               llvm::alignOf<NestedNameSpecifierAnnotation>());
+  NestedNameSpecifierAnnotation *Annotation
+    = new (Mem) NestedNameSpecifierAnnotation;
+  Annotation->NNS = SS.getScopeRep();
+  memcpy(Annotation + 1, SS.location_data(), SS.location_size());
+  return Annotation;
+}
+
+void Sema::RestoreNestedNameSpecifierAnnotation(void *AnnotationPtr, 
+                                                SourceRange AnnotationRange,
+                                                CXXScopeSpec &SS) {
+  if (!AnnotationPtr) {
+    SS.SetInvalid(AnnotationRange);
+    return;
+  }
+  
+  NestedNameSpecifierAnnotation *Annotation
+    = static_cast<NestedNameSpecifierAnnotation *>(AnnotationPtr);
+  SS.Adopt(NestedNameSpecifierLoc(Annotation->NNS, Annotation + 1));
+}
+
 bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
   assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
 
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 3094622..8e1792b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5085,8 +5085,10 @@
     // reference to operator=; this is required to suppress the virtual
     // call mechanism.
     CXXScopeSpec SS;
-    SS.Adopt(NestedNameSpecifier::Create(S.Context, 0, false, T.getTypePtr()),
-             Loc);
+    SS.MakeTrivial(S.Context, 
+                   NestedNameSpecifier::Create(S.Context, 0, false, 
+                                               T.getTypePtr()),
+                   Loc);
     
     // Create the reference to operator=.
     ExprResult OpEqualRef
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index c0e08c0..81bdbc6 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -107,7 +107,7 @@
       // Nothing left to do.
     } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) {
       CXXScopeSpec PrefixSS;
-      PrefixSS.Adopt(Prefix, SS.getRange());
+      PrefixSS.MakeTrivial(Context, Prefix, SS.getRange());
       LookupCtx = computeDeclContext(PrefixSS, EnteringContext);
       isDependent = isDependentScopeSpecifier(PrefixSS);
     } else if (ObjectTypePtr) {
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 7d3de8d..60873cd 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -7594,7 +7594,8 @@
 
   CXXScopeSpec SS;
   if (ULE->getQualifier())
-    SS.Adopt(ULE->getQualifier(), ULE->getQualifierRange());
+    SS.MakeTrivial(SemaRef.Context, 
+                   ULE->getQualifier(), ULE->getQualifierRange());
 
   TemplateArgumentListInfo TABuffer;
   const TemplateArgumentListInfo *ExplicitTemplateArgs = 0;
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index d75a1f1..474a18d 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3611,7 +3611,7 @@
         = NestedNameSpecifier::Create(Context, 0, false,
                                       ClassType.getTypePtr());
       CXXScopeSpec SS;
-      SS.Adopt(Qualifier, Loc);
+      SS.MakeTrivial(Context, Qualifier, Loc);
 
       // The actual value-ness of this is unimportant, but for
       // internal consistency's sake, references to instance methods
@@ -5998,7 +5998,7 @@
                         SourceLocation KeywordLoc, SourceRange NNSRange,
                         SourceLocation IILoc) {
   CXXScopeSpec SS;
-  SS.Adopt(NNS, NNSRange);
+  SS.MakeTrivial(Context, NNS, NNSRange);
 
   DeclContext *Ctx = computeDeclContext(SS);
   if (!Ctx) {
@@ -6177,7 +6177,7 @@
     Rebuilder.TransformNestedNameSpecifier(NNS, SS.getRange());
   if (!Rebuilt) return true;
 
-  SS.Adopt(Rebuilt, SS.getRange());
+  SS.MakeTrivial(Context, Rebuilt, SS.getRange());
   return false;
 }
 
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 73511fb..de4cd46 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -670,7 +670,7 @@
   if (isFriend) {
     if (Qualifier) {
       CXXScopeSpec SS;
-      SS.Adopt(Qualifier, Pattern->getQualifierRange());
+      SS.MakeTrivial(SemaRef.Context, Qualifier, Pattern->getQualifierRange());
       DC = SemaRef.computeDeclContext(SS);
       if (!DC) return 0;
     } else {
@@ -983,7 +983,7 @@
     DC = Owner;
   else if (isFriend && Qualifier) {
     CXXScopeSpec SS;
-    SS.Adopt(Qualifier, D->getQualifierRange());
+    SS.MakeTrivial(SemaRef.Context, Qualifier, D->getQualifierRange());
     DC = SemaRef.computeDeclContext(SS);
     if (!DC) return 0;
   } else {
@@ -1272,7 +1272,7 @@
   if (isFriend) {
     if (Qualifier) {
       CXXScopeSpec SS;
-      SS.Adopt(Qualifier, D->getQualifierRange());
+      SS.MakeTrivial(SemaRef.Context, Qualifier, D->getQualifierRange());
       DC = SemaRef.computeDeclContext(SS);
 
       if (DC && SemaRef.RequireCompleteDeclContext(SS, DC))
@@ -1688,7 +1688,7 @@
                                        D->isTypeName());
 
   CXXScopeSpec SS;
-  SS.Adopt(NNS, D->getNestedNameRange());
+  SS.MakeTrivial(SemaRef.Context, NNS, D->getNestedNameRange());
 
   if (CheckRedeclaration) {
     Prev.setHideTags(false);
@@ -1756,7 +1756,7 @@
     return 0;
 
   CXXScopeSpec SS;
-  SS.Adopt(NNS, D->getTargetNestedNameRange());
+  SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
 
   // Since NameInfo refers to a typename, it cannot be a C++ special name.
   // Hence, no tranformation is required for it.
@@ -1782,7 +1782,7 @@
     return 0;
 
   CXXScopeSpec SS;
-  SS.Adopt(NNS, D->getTargetNestedNameRange());
+  SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
 
   DeclarationNameInfo NameInfo
     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 1b2822e..fa0c2b9 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -759,7 +759,7 @@
                                     SourceRange NNSRange,
                                     SourceLocation IdLoc) {
     CXXScopeSpec SS;
-    SS.Adopt(NNS, NNSRange);
+    SS.MakeTrivial(SemaRef.Context, NNS, NNSRange);
 
     if (NNS->isDependent()) {
       // If the name is still dependent, just build a new dependent name type.
@@ -1252,7 +1252,7 @@
                                 const DeclarationNameInfo &NameInfo,
                                 TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
-    SS.Adopt(Qualifier, QualifierRange);
+    SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
 
     // FIXME: loses template args.
 
@@ -1391,7 +1391,7 @@
 
     CXXScopeSpec SS;
     if (Qualifier) {
-      SS.Adopt(Qualifier, QualifierRange);
+      SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
     }
 
     getSema().DefaultFunctionArrayConversion(Base);
@@ -1882,7 +1882,7 @@
                                        const DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
-    SS.Adopt(NNS, QualifierRange);
+    SS.MakeTrivial(SemaRef.Context, NNS, QualifierRange);
 
     if (TemplateArgs)
       return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo,
@@ -1967,7 +1967,7 @@
                                    const DeclarationNameInfo &MemberNameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
-    SS.Adopt(Qualifier, QualifierRange);
+    SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
 
     return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
                                             OperatorLoc, IsArrow,
@@ -1990,7 +1990,7 @@
                                                LookupResult &R,
                                 const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
-    SS.Adopt(Qualifier, QualifierRange);
+    SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
 
     return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
                                             OperatorLoc, IsArrow,
@@ -6467,7 +6467,7 @@
     // Look for a destructor known with the given name.
     CXXScopeSpec SS;
     if (Qualifier)
-      SS.Adopt(Qualifier, E->getQualifierRange());
+      SS.MakeTrivial(SemaRef.Context, Qualifier, E->getQualifierRange());
     
     ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
                                               *E->getDestroyedTypeIdentifier(),
@@ -6550,7 +6550,7 @@
     if (!Qualifier)
       return ExprError();
     
-    SS.Adopt(Qualifier, Old->getQualifierRange());
+    SS.MakeTrivial(SemaRef.Context, Qualifier, Old->getQualifierRange());
   } 
   
   if (Old->getNamingClass()) {
@@ -7571,7 +7571,7 @@
                                                    NamedDecl *FirstQualifierInScope) {
   CXXScopeSpec SS;
   // FIXME: The source location information is all wrong.
-  SS.Adopt(Prefix, Range);
+  SS.MakeTrivial(SemaRef.Context, Prefix, Range);
   if (SemaRef.BuildCXXNestedNameSpecifier(0, II, /*FIXME:*/Range.getBegin(),
                                           /*FIXME:*/Range.getEnd(),
                                           ObjectType, false,
@@ -7632,7 +7632,7 @@
                                             QualType ObjectType,
                                             NamedDecl *FirstQualifierInScope) {
   CXXScopeSpec SS;
-  SS.Adopt(Qualifier, QualifierRange);
+  SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
   UnqualifiedId Name;
   Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
   Sema::TemplateTy Template;
@@ -7652,7 +7652,7 @@
                                             OverloadedOperatorKind Operator,
                                             QualType ObjectType) {
   CXXScopeSpec SS;
-  SS.Adopt(Qualifier, SourceRange(getDerived().getBaseLocation()));
+  SS.MakeTrivial(SemaRef.Context, Qualifier, SourceRange(getDerived().getBaseLocation()));
   UnqualifiedId Name;
   SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
   Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
@@ -7766,7 +7766,7 @@
                                         PseudoDestructorTypeStorage Destroyed) {
   CXXScopeSpec SS;
   if (Qualifier)
-    SS.Adopt(Qualifier, QualifierRange);
+    SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
 
   QualType BaseType = Base->getType();
   if (Base->isTypeDependent() || Destroyed.getIdentifier() ||