Remove use of 'std::string' from Attr objects, using instead a byte
array allocated using the allocator in ASTContext.  This addresses
these strings getting leaked when using a BumpPtrAllocator (in
ASTContext).

Fixes: <rdar://problem/7636765>


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95853 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index 42c099d..d835edf 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -11,11 +11,45 @@
 //
 //===----------------------------------------------------------------------===//
 
-
 #include "clang/AST/Attr.h"
 #include "clang/AST/ASTContext.h"
 using namespace clang;
 
+void Attr::Destroy(ASTContext &C) {
+  if (Next) {
+    Next->Destroy(C);
+    Next = 0;
+  }
+  this->~Attr();
+  C.Deallocate((void*)this);
+}
+
+AttrWithString::AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s)
+  : Attr(AK) {
+  assert(!s.empty());
+  StrLen = s.size();
+  Str = new (C) char[StrLen];
+  memcpy(const_cast<char*>(Str), s.data(), StrLen);
+}
+
+void AttrWithString::Destroy(ASTContext &C) {
+  C.Deallocate(const_cast<char*>(Str));  
+  Attr::Destroy(C);
+}
+
+void AttrWithString::ReplaceString(ASTContext &C, llvm::StringRef newS) {
+  if (newS.size() > StrLen) {
+    C.Deallocate(const_cast<char*>(Str));
+    Str = new char[newS.size()];
+  }
+  StrLen = newS.size();
+  memcpy(const_cast<char*>(Str), newS.data(), StrLen);
+}
+
+void FormatAttr::setType(ASTContext &C, llvm::StringRef type) {
+  ReplaceString(C, type);
+}
+
 #define DEF_SIMPLE_ATTR_CLONE(ATTR)                                     \
   Attr *ATTR##Attr::clone(ASTContext &C) const {                        \
     return ::new (C) ATTR##Attr;                                        \
@@ -66,15 +100,15 @@
 }
 
 Attr* AnnotateAttr::clone(ASTContext &C) const {
-  return ::new (C) AnnotateAttr(Annotation);
+  return ::new (C) AnnotateAttr(C, getAnnotation());
 }
 
 Attr *AsmLabelAttr::clone(ASTContext &C) const {
-  return ::new (C) AsmLabelAttr(Label);
+  return ::new (C) AsmLabelAttr(C, getLabel());
 }
 
 Attr *AliasAttr::clone(ASTContext &C) const {
-  return ::new (C) AliasAttr(Aliasee);
+  return ::new (C) AliasAttr(C, getAliasee());
 }
 
 Attr *ConstructorAttr::clone(ASTContext &C) const {
@@ -94,7 +128,7 @@
 }
 
 Attr *SectionAttr::clone(ASTContext &C) const {
-  return ::new (C) SectionAttr(Name);
+  return ::new (C) SectionAttr(C, getName());
 }
 
 Attr *NonNullAttr::clone(ASTContext &C) const {
@@ -102,7 +136,7 @@
 }
 
 Attr *FormatAttr::clone(ASTContext &C) const {
-  return ::new (C) FormatAttr(Type, formatIdx, firstArg);
+  return ::new (C) FormatAttr(C, getType(), formatIdx, firstArg);
 }
 
 Attr *FormatArgAttr::clone(ASTContext &C) const {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 4851636..5acb82f 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -29,15 +29,6 @@
 
 using namespace clang;
 
-void Attr::Destroy(ASTContext &C) {
-  if (Next) {
-    Next->Destroy(C);
-    Next = 0;
-  }
-  this->~Attr();
-  C.Deallocate((void*)this);
-}
-
 /// \brief Return the TypeLoc wrapper for the type source info.
 TypeLoc TypeSourceInfo::getTypeLoc() const {
   return TypeLoc(Ty, (void*)(this + 1));
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index a6b546e..5a552c4 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1283,8 +1283,8 @@
   const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
 
   // Unique the name through the identifier table.
-  const char *AliaseeName = AA->getAliasee().c_str();
-  AliaseeName = getContext().Idents.get(AliaseeName).getNameStart();
+  const char *AliaseeName =
+    getContext().Idents.get(AA->getAliasee()).getNameStart();
 
   // Create a reference to the named value.  This ensures that it is emitted
   // if a deferred decl.
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 43f0b2c..29f5556 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -446,7 +446,7 @@
 
 #define STRING_ATTR(Name)                                       \
  case Attr::Name:                                               \
-   New = ::new (*Context) Name##Attr(ReadString(Record, Idx));  \
+   New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx));  \
    break
 
 #define UNSIGNED_ATTR(Name)                             \
@@ -497,7 +497,7 @@
       std::string Type = ReadString(Record, Idx);
       unsigned FormatIdx = Record[Idx++];
       unsigned FirstArg = Record[Idx++];
-      New = ::new (*Context) FormatAttr(Type, FormatIdx, FirstArg);
+      New = ::new (*Context) FormatAttr(*Context, Type, FormatIdx, FirstArg);
       break;
     }
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d7ca5ab..e6b047a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2387,7 +2387,7 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
-    NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getString()));
+    NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
   }
 
   // Don't consider existing declarations that are in a different
@@ -2910,7 +2910,7 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
-    NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getString()));
+    NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
   }
 
   // Copy the parameter declarations from the declarator D to the function
@@ -4315,8 +4315,8 @@
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
       if (!FD->getAttr<FormatAttr>())
-        FD->addAttr(::new (Context) FormatAttr("printf", FormatIdx + 1,
-                                             HasVAListArg ? 0 : FormatIdx + 2));
+        FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+                                               HasVAListArg ? 0 : FormatIdx+2));
     }
 
     // Mark const if we don't care about errno and that is the only
@@ -4353,15 +4353,15 @@
     // FIXME: NSLog and NSLogv should be target specific
     if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
       // FIXME: We known better than our headers.
-      const_cast<FormatAttr *>(Format)->setType("printf");
+      const_cast<FormatAttr *>(Format)->setType(Context, "printf");
     } else
-      FD->addAttr(::new (Context) FormatAttr("printf", 1,
+      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
                                              Name->isStr("NSLogv") ? 0 : 2));
   } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
     // FIXME: asprintf and vasprintf aren't C99 functions. Should they be
     // target-specific builtins, perhaps?
     if (!FD->getAttr<FormatAttr>())
-      FD->addAttr(::new (Context) FormatAttr("printf", 2,
+      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2,
                                              Name->isStr("vasprintf") ? 0 : 3));
   }
 }
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 01e8fda..e592fd2 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -329,7 +329,7 @@
 
   // FIXME: check if target symbol exists in current file
 
-  d->addAttr(::new (S.Context) AliasAttr(Str->getString()));
+  d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
 }
 
 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -942,7 +942,7 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) SectionAttr(SE->getString()));
+  D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
 }
 
 
@@ -1257,7 +1257,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatAttr(Format, Idx.getZExtValue(),
+  d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
                                           FirstArg.getZExtValue()));
 }
 
@@ -1343,7 +1343,7 @@
     S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
     return;
   }
-  d->addAttr(::new (S.Context) AnnotateAttr(SE->getString()));
+  d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
 }
 
 static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1924,7 +1924,7 @@
   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
     IdentifierInfo *NDId = ND->getIdentifier();
     NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
-    NewD->addAttr(::new (Context) AliasAttr(NDId->getName()));
+    NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
     NewD->addAttr(::new (Context) WeakAttr());
     WeakTopLevelDecl.push_back(NewD);
     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin