diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2016-02-13 18:11:49 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2016-02-13 18:11:49 +0000 |
commit | 1b5820133f16e12113e759096ad37db0a748b75d (patch) | |
tree | 73da2c4e2c7823e5ba0e2258d2384b3e4a1f4114 /clang/utils/TableGen | |
parent | bcdb0f2ede595be12d12c44a68fb9dc6a27e730f (diff) | |
download | bcm5719-llvm-1b5820133f16e12113e759096ad37db0a748b75d.tar.gz bcm5719-llvm-1b5820133f16e12113e759096ad37db0a748b75d.zip |
Fix a leak in the generated code for attributes with strings.
Storing std::strings in attributes simply doesn't work, we never call
the destructor. Use an array of StringRefs instead of std::strings and
copy the data into memory taken from the ASTContext.
llvm-svn: 260831
Diffstat (limited to 'clang/utils/TableGen')
-rw-r--r-- | clang/utils/TableGen/ClangAttrEmitter.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index c0574449acc..4a272d6bb79 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -81,7 +81,7 @@ static std::string ReadPCHRecord(StringRef type) { .Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)") .Case("Expr *", "ReadExpr(F)") .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") - .Case("std::string", "ReadString(Record, Idx)") + .Case("StringRef", "ReadString(Record, Idx)") .Default("Record[Idx++]"); } @@ -95,7 +95,7 @@ static std::string WritePCHRecord(StringRef type, StringRef name) { .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") .Case("IdentifierInfo *", "AddIdentifierRef(" + std::string(name) + ", Record);\n") - .Case("std::string", "AddString(" + std::string(name) + ", Record);\n") + .Case("StringRef", "AddString(" + std::string(name) + ", Record);\n") .Default("Record.push_back(" + std::string(name) + ");\n"); } @@ -528,7 +528,9 @@ namespace { : Argument(Arg, Attr), Type(T), ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"), RangeName(getLowerName()) {} - std::string getType() const { return Type; } + const std::string &getType() const { return Type; } + const std::string &getArgName() const { return ArgName; } + const std::string &getArgSizeName() const { return ArgSizeName; } bool isVariadic() const override { return true; } void writeAccessors(raw_ostream &OS) const override { @@ -993,8 +995,19 @@ namespace { class VariadicStringArgument : public VariadicArgument { public: VariadicStringArgument(const Record &Arg, StringRef Attr) - : VariadicArgument(Arg, Attr, "std::string") + : VariadicArgument(Arg, Attr, "StringRef") {} + void writeCtorBody(raw_ostream &OS) const override { + OS << " for (size_t I = 0, E = " << getArgSizeName() << "; I != E;\n" + " ++I) {\n" + " StringRef Ref = " << getUpperName() << "[I];\n" + " if (!Ref.empty()) {\n" + " char *Mem = new (Ctx, 1) char[Ref.size()];\n" + " std::memcpy(Mem, Ref.data(), Ref.size());\n" + " " << getArgName() << "[I] = StringRef(Mem, Ref.size());\n" + " }\n" + " }"; + } void writeValueImpl(raw_ostream &OS) const override { OS << " OS << \"\\\"\" << Val << \"\\\"\";\n"; } |