Remember declaration scope qualifiers in the AST.  Imposes no memory overhead
on unqualified declarations.

Patch by Enea Zaffanella!  Minimal adjustments:  allocate the ExtInfo nodes
with the ASTContext and delete them during Destroy().  I audited a bunch of
Destroy methods at the same time, to ensure that the correct teardown was
being done.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98540 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 23f5fba..f568d1c 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -495,9 +495,16 @@
 // DeclaratorDecl Implementation
 //===----------------------------------------------------------------------===//
 
+DeclaratorDecl::~DeclaratorDecl() {}
+void DeclaratorDecl::Destroy(ASTContext &C) {
+  if (hasExtInfo())
+    C.Deallocate(getExtInfo());
+  ValueDecl::Destroy(C);
+}
+
 SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
   if (DeclInfo) {
-    TypeLoc TL = DeclInfo->getTypeLoc();
+    TypeLoc TL = getTypeSourceInfo()->getTypeLoc();
     while (true) {
       TypeLoc NextTL = TL.getNextTypeLoc();
       if (!NextTL)
@@ -508,6 +515,36 @@
   return SourceLocation();
 }
 
+void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
+                                      SourceRange QualifierRange) {
+  if (Qualifier) {
+    // Make sure the extended decl info is allocated.
+    if (!hasExtInfo()) {
+      // Save (non-extended) type source info pointer.
+      TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
+      // Allocate external info struct.
+      DeclInfo = new (getASTContext()) ExtInfo;
+      // Restore savedTInfo into (extended) decl info.
+      getExtInfo()->TInfo = savedTInfo;
+    }
+    // Set qualifier info.
+    getExtInfo()->NNS = Qualifier;
+    getExtInfo()->NNSRange = QualifierRange;
+  }
+  else {
+    // Here Qualifier == 0, i.e., we are removing the qualifier (if any).
+    assert(QualifierRange.isInvalid());
+    if (hasExtInfo()) {
+      // Save type source info pointer.
+      TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
+      // Deallocate the extended decl info.
+      getASTContext().Deallocate(getExtInfo());
+      // Restore savedTInfo into (non-extended) decl info.
+      DeclInfo = savedTInfo;
+    }
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // VarDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -542,7 +579,7 @@
     }
   }
   this->~VarDecl();
-  C.Deallocate((void *)this);
+  DeclaratorDecl::Destroy(C);
 }
 
 VarDecl::~VarDecl() {
@@ -818,7 +855,7 @@
   
   C.Deallocate(ParamInfo);
 
-  Decl::Destroy(C);
+  DeclaratorDecl::Destroy(C);
 }
 
 void FunctionDecl::getNameForDiagnostic(std::string &S,
@@ -1348,6 +1385,12 @@
 // TagDecl Implementation
 //===----------------------------------------------------------------------===//
 
+void TagDecl::Destroy(ASTContext &C) {
+  if (hasExtInfo())
+    C.Deallocate(getExtInfo());
+  TypeDecl::Destroy(C);
+}
+
 SourceRange TagDecl::getSourceRange() const {
   SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
   return SourceRange(TagKeywordLoc, E);
@@ -1409,6 +1452,26 @@
   }
 }
 
+void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
+                               SourceRange QualifierRange) {
+  if (Qualifier) {
+    // Make sure the extended qualifier info is allocated.
+    if (!hasExtInfo())
+      TypedefDeclOrQualifier = new (getASTContext()) ExtInfo;
+    // Set qualifier info.
+    getExtInfo()->NNS = Qualifier;
+    getExtInfo()->NNSRange = QualifierRange;
+  }
+  else {
+    // Here Qualifier == 0, i.e., we are removing the qualifier (if any).
+    assert(QualifierRange.isInvalid());
+    if (hasExtInfo()) {
+      getASTContext().Deallocate(getExtInfo());
+      TypedefDeclOrQualifier = (TypedefDecl*) 0;
+    }
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // EnumDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -1422,7 +1485,7 @@
 }
 
 void EnumDecl::Destroy(ASTContext& C) {
-  Decl::Destroy(C);
+  TagDecl::Destroy(C);
 }
 
 void EnumDecl::completeDefinition(QualType NewType,
@@ -1529,7 +1592,7 @@
   // together. They are all top-level Decls.
 
   this->~NamespaceDecl();
-  C.Deallocate((void *)this);
+  Decl::Destroy(C);
 }
 
 
@@ -1563,7 +1626,7 @@
 
 void EnumConstantDecl::Destroy(ASTContext& C) {
   if (Init) Init->Destroy(C);
-  Decl::Destroy(C);
+  ValueDecl::Destroy(C);
 }
 
 TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,