diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 0125985c1cb6..ab8e2c649d5c 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -18,7 +18,6 @@ #include "llvm/ADT/StringRef.h" #include #include -#include #include using llvm::dyn_cast; @@ -120,8 +119,7 @@ protected: assert(Next == 0 && "Destroy didn't work"); } public: - - void Destroy(ASTContext &C); + virtual void Destroy(ASTContext &C); /// \brief Whether this attribute should be merged to new /// declarations. @@ -157,6 +155,18 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *) { return true; } }; + +class AttrWithString : public Attr { +private: + const char *Str; + unsigned StrLen; +protected: + AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s); + llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); } + void ReplaceString(ASTContext &C, llvm::StringRef newS); +public: + virtual void Destroy(ASTContext &C); +}; #define DEF_SIMPLE_ATTR(ATTR) \ class ATTR##Attr : public Attr { \ @@ -214,12 +224,12 @@ public: static bool classof(const AlignedAttr *A) { return true; } }; -class AnnotateAttr : public Attr { - std::string Annotation; +class AnnotateAttr : public AttrWithString { public: - AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {} + AnnotateAttr(ASTContext &C, llvm::StringRef ann) + : AttrWithString(Annotate, C, ann) {} - const std::string& getAnnotation() const { return Annotation; } + llvm::StringRef getAnnotation() const { return getString(); } virtual Attr* clone(ASTContext &C) const; @@ -230,12 +240,12 @@ public: static bool classof(const AnnotateAttr *A) { return true; } }; -class AsmLabelAttr : public Attr { - std::string Label; +class AsmLabelAttr : public AttrWithString { public: - AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {} + AsmLabelAttr(ASTContext &C, llvm::StringRef L) + : AttrWithString(AsmLabel, C, L) {} - const std::string& getLabel() const { return Label; } + llvm::StringRef getLabel() const { return getString(); } virtual Attr* clone(ASTContext &C) const; @@ -248,12 +258,12 @@ public: DEF_SIMPLE_ATTR(AlwaysInline); -class AliasAttr : public Attr { - std::string Aliasee; +class AliasAttr : public AttrWithString { public: - AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {} + AliasAttr(ASTContext &C, llvm::StringRef aliasee) + : AttrWithString(Alias, C, aliasee) {} - const std::string& getAliasee() const { return Aliasee; } + llvm::StringRef getAliasee() const { return getString(); } virtual Attr *clone(ASTContext &C) const; @@ -322,12 +332,12 @@ DEF_SIMPLE_ATTR(AnalyzerNoReturn); DEF_SIMPLE_ATTR(Deprecated); DEF_SIMPLE_ATTR(Final); -class SectionAttr : public Attr { - std::string Name; +class SectionAttr : public AttrWithString { public: - SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {} + SectionAttr(ASTContext &C, llvm::StringRef N) + : AttrWithString(Section, C, N) {} - const std::string& getName() const { return Name; } + llvm::StringRef getName() const { return getString(); } virtual Attr *clone(ASTContext &C) const; @@ -380,15 +390,14 @@ public: static bool classof(const NonNullAttr *A) { return true; } }; -class FormatAttr : public Attr { - std::string Type; +class FormatAttr : public AttrWithString { int formatIdx, firstArg; public: - FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format), - Type(type), formatIdx(idx), firstArg(first) {} + FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first) + : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {} - const std::string& getType() const { return Type; } - void setType(llvm::StringRef type) { Type = type; } + llvm::StringRef getType() const { return getString(); } + void setType(ASTContext &C, llvm::StringRef type); int getFormatIdx() const { return formatIdx; } int getFirstArg() const { return firstArg; } diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index 42c099d66c6b..d835edf0b324 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/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(Str), s.data(), StrLen); +} + +void AttrWithString::Destroy(ASTContext &C) { + C.Deallocate(const_cast(Str)); + Attr::Destroy(C); +} + +void AttrWithString::ReplaceString(ASTContext &C, llvm::StringRef newS) { + if (newS.size() > StrLen) { + C.Deallocate(const_cast(Str)); + Str = new char[newS.size()]; + } + StrLen = newS.size(); + memcpy(const_cast(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* AlignedAttr::clone(ASTContext &C) const { } 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 *GNUInlineAttr::clone(ASTContext &C) const { } 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 *NonNullAttr::clone(ASTContext &C) const { } 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/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 48516364c67b..5acb82f31a29 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/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/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a6b546ef9ef0..5a552c490ac6 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1283,8 +1283,8 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { 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/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index 43f0b2c5cda3..29f5556b1934 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -446,7 +446,7 @@ Attr *PCHReader::ReadAttributes() { #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 @@ Attr *PCHReader::ReadAttributes() { 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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d7ca5ab6ccdc..e6b047a959d4 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2387,7 +2387,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (Expr *E = (Expr*) D.getAsmLabel()) { // The parser guarantees this is a string. StringLiteral *SE = cast(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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (Expr *E = (Expr*) D.getAsmLabel()) { // The parser guarantees this is a string. StringLiteral *SE = cast(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 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { bool HasVAListArg; if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) { if (!FD->getAttr()) - 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 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // FIXME: NSLog and NSLogv should be target specific if (const FormatAttr *Format = FD->getAttr()) { // FIXME: We known better than our headers. - const_cast(Format)->setType("printf"); + const_cast(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()) - FD->addAttr(::new (Context) FormatAttr("printf", 2, + FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2, Name->isStr("vasprintf") ? 0 : 3)); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 01e8fda2ebf1..e592fd2f5564 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -329,7 +329,7 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { return; } - D->addAttr(::new (S.Context) SectionAttr(SE->getString())); + D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString())); } @@ -1257,7 +1257,7 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 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