From ced10529fed6a49b7bf512657586c4fba4c21495 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 19 Dec 2013 19:33:35 +0000 Subject: [PATCH] No longer leaking Argument objects after calling createArgument. However, since an OwningPtr cannot live in a std::vector yet, there are some manual deletions that have a FIXME attached to them. These will go away once C++11 support is allowed. llvm-svn: 197715 --- clang/utils/TableGen/ClangAttrEmitter.cpp | 76 ++++++++++++++++------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index d32f3a61e884..1e33ae095f9e 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -892,41 +892,45 @@ namespace { getType(), "SA->get" + std::string(getUpperName()) + "Loc()"); } }; + + typedef OwningPtr OwnedArgument; } -static Argument *createArgument(Record &Arg, StringRef Attr, - Record *Search = 0) { +static OwnedArgument createArgument(Record &Arg, StringRef Attr, + Record *Search = 0) { if (!Search) Search = &Arg; - Argument *Ptr = 0; + OwnedArgument Ptr; llvm::StringRef ArgName = Search->getName(); - if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr); - else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr); - else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr); + if (ArgName == "AlignedArgument") Ptr.reset(new AlignedArgument(Arg, Attr)); + else if (ArgName == "EnumArgument") Ptr.reset(new EnumArgument(Arg, Attr)); + else if (ArgName == "ExprArgument") Ptr.reset(new ExprArgument(Arg, Attr)); else if (ArgName == "FunctionArgument") - Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *"); + Ptr.reset(new SimpleArgument(Arg, Attr, "FunctionDecl *")); else if (ArgName == "IdentifierArgument") - Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *"); - else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, - "bool"); + Ptr.reset(new SimpleArgument(Arg, Attr, "IdentifierInfo *")); + else if (ArgName == "BoolArgument") Ptr.reset(new SimpleArgument(Arg, Attr, + "bool")); else if (ArgName == "DefaultIntArgument") - Ptr = new DefaultSimpleArgument(Arg, Attr, "int", - Arg.getValueAsInt("Default")); - else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); - else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); - else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr); + Ptr.reset(new DefaultSimpleArgument(Arg, Attr, "int", + Arg.getValueAsInt("Default"))); + else if (ArgName == "IntArgument") + Ptr.reset(new SimpleArgument(Arg, Attr, "int")); + else if (ArgName == "StringArgument") + Ptr.reset(new StringArgument(Arg, Attr)); + else if (ArgName == "TypeArgument") Ptr.reset(new TypeArgument(Arg, Attr)); else if (ArgName == "UnsignedArgument") - Ptr = new SimpleArgument(Arg, Attr, "unsigned"); + Ptr.reset(new SimpleArgument(Arg, Attr, "unsigned")); else if (ArgName == "VariadicUnsignedArgument") - Ptr = new VariadicArgument(Arg, Attr, "unsigned"); + Ptr.reset(new VariadicArgument(Arg, Attr, "unsigned")); else if (ArgName == "VariadicEnumArgument") - Ptr = new VariadicEnumArgument(Arg, Attr); + Ptr.reset(new VariadicEnumArgument(Arg, Attr)); else if (ArgName == "VariadicExprArgument") - Ptr = new VariadicExprArgument(Arg, Attr); + Ptr.reset(new VariadicExprArgument(Arg, Attr)); else if (ArgName == "VersionArgument") - Ptr = new VersionArgument(Arg, Attr); + Ptr.reset(new VersionArgument(Arg, Attr)); if (!Ptr) { // Search in reverse order so that the most-derived type is handled first. @@ -1117,7 +1121,8 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { re = ArgRecords.end(); ri != re; ++ri) { Record &ArgRecord = **ri; - Argument *Arg = createArgument(ArgRecord, R.getName()); + // FIXME: when C++11 is allowed, the .take() can disappear. + Argument *Arg = createArgument(ArgRecord, R.getName()).take(); assert(Arg); Args.push_back(Arg); @@ -1224,6 +1229,11 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { << LateParsed << "; }\n"; OS << "};\n\n"; + + // FIXME: when C++11 is allowed, the delete can disappear along with the + // take(). + for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) + delete *ai; } OS << "#endif\n"; @@ -1313,7 +1323,8 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { std::vector ArgRecords = R.getValueAsListOfDefs("Args"); std::vector Args; for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) - Args.push_back(createArgument(**ri, R.getName())); + // FIXME: when C++11 is allowed, the .take() can disappear. + Args.push_back(createArgument(**ri, R.getName()).take()); for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) (*ai)->writeAccessorDefinitions(OS); @@ -1328,6 +1339,11 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { OS << ", getSpellingListIndex());\n}\n\n"; writePrettyPrintFunction(R, Args, OS); + + // FIXME: when C++11 is allowed, the delete can disappear along with the + // take(). + for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) + delete *ai; } } @@ -1431,7 +1447,8 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { ArgRecords = R.getValueAsListOfDefs("Args"); Args.clear(); for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { - Argument *A = createArgument(**ai, R.getName()); + // FIXME: when C++11 is allowed, the .take() can disappear. + Argument *A = createArgument(**ai, R.getName()).take(); Args.push_back(A); A->writePCHReadDecls(OS); } @@ -1445,6 +1462,11 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { OS << " cast(New)->setInherited(isInherited);\n"; OS << " break;\n"; OS << " }\n"; + + // FIXME: when C++11 is allowed, the delete can disappear along with the + // take(). + for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) + delete *ri; } OS << " }\n"; } @@ -1621,7 +1643,8 @@ void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { re = ArgRecords.end(); ri != re; ++ri) { Record &ArgRecord = **ri; - Argument *Arg = createArgument(ArgRecord, R.getName()); + // FIXME: when C++11 is allowed, the .take() can disappear. + Argument *Arg = createArgument(ArgRecord, R.getName()).take(); assert(Arg); Args.push_back(Arg); } @@ -1636,6 +1659,11 @@ void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { (*ai)->writeTemplateInstantiationArgs(OS); } OS << ");\n }\n"; + + // FIXME: when C++11 is allowed, the delete can disappear along with the + // take(). + for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) + delete *ai; } OS << " } // end switch\n" << " llvm_unreachable(\"Unknown attribute!\");\n"