Don't build identifiers for C++ constructors, destructors, or
conversion functions. Instead, we just use a placeholder identifier
for these (e.g., "<constructor>") and override NamedDecl::getName() to
provide a human-readable name.

This is one potential solution to the problem; another solution would
be to replace the use of IdentifierInfo* in NamedDecl with a different
class that deals with identifiers better. I'm also prototyping that to
see how it compares, but this commit is better than what we had
previously.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59193 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index d008544..1de6407 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -13,6 +13,7 @@
 
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/Basic/IdentifierTable.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -26,11 +27,20 @@
   return new (Mem) CXXFieldDecl(RD, L, Id, T, BW);
 }
 
+CXXRecordDecl::CXXRecordDecl(ASTContext &C, TagKind TK, DeclContext *DC,
+                             SourceLocation L, IdentifierInfo *Id) 
+  : RecordDecl(CXXRecord, TK, DC, L, Id), DeclContext(CXXRecord),
+    UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
+    Aggregate(true), Polymorphic(false), Bases(0), NumBases(0),
+    Constructors(DC, &C.Idents.getConstructorId()), 
+    Destructor(0), 
+    Conversions(DC, &C.Idents.getConversionFunctionId()) { }
+
 CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
                                      SourceLocation L, IdentifierInfo *Id,
                                      CXXRecordDecl* PrevDecl) {
   void *Mem = C.getAllocator().Allocate<CXXRecordDecl>();
-  CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id);
+  CXXRecordDecl* R = new (Mem) CXXRecordDecl(C, TK, DC, L, Id);
   C.getTypeDeclType(R, PrevDecl);  
   return R;
 }
@@ -232,6 +242,10 @@
          (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
 }
 
+const char *CXXConstructorDecl::getName() const { 
+  return getParent()->getName();
+}
+
 CXXDestructorDecl *
 CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                           SourceLocation L, IdentifierInfo *Id,
@@ -242,6 +256,34 @@
                                      isImplicitlyDeclared);
 }
 
+CXXDestructorDecl::~CXXDestructorDecl() {
+  delete [] Name;
+}
+
+const char *CXXDestructorDecl::getName() const {
+  if (!Name) {
+    std::string Builder = "~";
+    Builder += getParent()->getName();
+    Name = new char[Builder.size()+1];
+    strcpy(Name, Builder.c_str());
+  }
+  return Name;
+}
+
+CXXConversionDecl::~CXXConversionDecl() {
+  delete [] Name;
+}
+
+const char *CXXConversionDecl::getName() const {
+  if (!Name) {
+    std::string Builder = "operator ";
+    Builder += getConversionType().getAsString();
+    Name = new char[Builder.size()+1];
+    strcpy(Name, Builder.c_str());    
+  }
+  return Name;
+}
+
 CXXConversionDecl *
 CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                           SourceLocation L, IdentifierInfo *Id,