IIRC TableGen has plenty of leaks, but I agree on the principle of the thing.
On Mar 5, 2014, at 8:49 , Aaron Ballman <[email protected]> wrote: > Author: aaronballman > Date: Wed Mar 5 10:49:55 2014 > New Revision: 202989 > > URL: http://llvm.org/viewvc/llvm-project?rev=202989&view=rev > Log: > [C++11] Using std::unique_ptr to ensure that Argument objects do not leak > (since clang-tblgen isn't long-lived, the old leak is probably acceptable, > but it offended my senses nonetheless). > > Modified: > cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp > > Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=202989&r1=202988&r2=202989&view=diff > ============================================================================== > --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) > +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Wed Mar 5 10:49:55 2014 > @@ -21,6 +21,7 @@ > #include "llvm/TableGen/TableGenBackend.h" > #include <algorithm> > #include <cctype> > +#include <memory> > #include <set> > #include <sstream> > > @@ -967,8 +968,8 @@ namespace { > }; > } > > -static Argument *createArgument(Record &Arg, StringRef Attr, > - Record *Search = 0) { > +static std::unique_ptr<Argument> createArgument(Record &Arg, StringRef Attr, > + Record *Search = 0) { > if (!Search) > Search = &Arg; > > @@ -1008,7 +1009,7 @@ static Argument *createArgument(Record & > // Search in reverse order so that the most-derived type is handled first. > std::vector<Record*> Bases = Search->getSuperClasses(); > for (auto i = Bases.rbegin(), e = Bases.rend(); i != e; ++i) { > - Ptr = createArgument(Arg, Attr, *i); > + Ptr = createArgument(Arg, Attr, *i).release(); > if (Ptr) > break; > } > @@ -1017,7 +1018,7 @@ static Argument *createArgument(Record & > if (Ptr && Arg.getValueAsBit("Optional")) > Ptr->setOptional(true); > > - return Ptr; > + return std::unique_ptr<Argument>(Ptr); > } > > static void writeAvailabilityValue(raw_ostream &OS) { > @@ -1052,8 +1053,10 @@ static void writeGetSpellingFunction(Rec > OS << "}\n\n"; > } > > -static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args, > - raw_ostream &OS) { > +static void > +writePrettyPrintFunction(Record &R, > + const std::vector<std::unique_ptr<Argument>> &Args, > + raw_ostream &OS) { > std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); > > OS << "void " << R.getName() << "Attr::printPretty(" > @@ -1106,7 +1109,8 @@ static void writePrettyPrintFunction(Rec > " case " << I << " : {\n" > " OS << \"" + Prefix.str() + Spelling.str(); > > - if (Args.size()) OS << "("; > + if (!Args.empty()) > + OS << "("; > if (Spelling == "availability") { > writeAvailabilityValue(OS); > } else { > @@ -1116,7 +1120,8 @@ static void writePrettyPrintFunction(Rec > } > } > > - if (Args.size()) OS << ")"; > + if (!Args.empty()) > + OS << ")"; > OS << Suffix.str() + "\";\n"; > > OS << > @@ -1379,15 +1384,12 @@ void EmitClangAttrClass(RecordKeeper &Re > OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; > > std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); > - std::vector<Argument*> Args; > + std::vector<std::unique_ptr<Argument>> Args; > Args.reserve(ArgRecords.size()); > > for (auto ArgRecord : ArgRecords) { > - Argument *Arg = createArgument(*ArgRecord, R.getName()); > - assert(Arg); > - Args.push_back(Arg); > - > - Arg->writeDeclarations(OS); > + Args.emplace_back(createArgument(*ArgRecord, R.getName())); > + Args.back()->writeDeclarations(OS); > OS << "\n\n"; > } > > @@ -1411,7 +1413,7 @@ void EmitClangAttrClass(RecordKeeper &Re > OS << "ASTContext &Ctx"; > if (!ElideSpelling) > OS << ", Spelling S"; > - for (auto ai : Args) { > + for (auto const &ai : Args) { > OS << ", "; > ai->writeCtorParameters(OS); > } > @@ -1419,7 +1421,7 @@ void EmitClangAttrClass(RecordKeeper &Re > OS << ") {\n"; > OS << " " << R.getName() << "Attr *A = new (Ctx) " << R.getName(); > OS << "Attr(Loc, Ctx, "; > - for (auto ai : Args) { > + for (auto const &ai : Args) { > ai->writeImplicitCtorArgs(OS); > OS << ", "; > } > @@ -1430,7 +1432,7 @@ void EmitClangAttrClass(RecordKeeper &Re > OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; > > bool HasOpt = false; > - for (auto ai : Args) { > + for (auto const &ai : Args) { > OS << " , "; > ai->writeCtorParameters(OS); > OS << "\n"; > @@ -1444,7 +1446,7 @@ void EmitClangAttrClass(RecordKeeper &Re > OS << " )\n"; > OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; > > - for (auto ai : Args) { > + for (auto const &ai : Args) { > OS << " , "; > ai->writeCtorInitializers(OS); > OS << "\n"; > @@ -1452,7 +1454,7 @@ void EmitClangAttrClass(RecordKeeper &Re > > OS << " {\n"; > > - for (auto ai : Args) { > + for (auto const &ai : Args) { > ai->writeCtorBody(OS); > OS << "\n"; > } > @@ -1462,7 +1464,7 @@ void EmitClangAttrClass(RecordKeeper &Re > // optional arguments as well. > if (HasOpt) { > OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; > - for (auto ai : Args) { > + for (auto const &ai : Args) { > if (!ai->isOptional()) { > OS << " , "; > ai->writeCtorParameters(OS); > @@ -1476,7 +1478,7 @@ void EmitClangAttrClass(RecordKeeper &Re > OS << " )\n"; > OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; > > - for (auto ai : Args) { > + for (auto const &ai : Args) { > OS << " , "; > ai->writeCtorDefaultInitializers(OS); > OS << "\n"; > @@ -1484,7 +1486,7 @@ void EmitClangAttrClass(RecordKeeper &Re > > OS << " {\n"; > > - for (auto ai : Args) { > + for (auto const &ai : Args) { > if (!ai->isOptional()) { > ai->writeCtorBody(OS); > OS << "\n"; > @@ -1508,14 +1510,15 @@ void EmitClangAttrClass(RecordKeeper &Re > > writeAttrAccessorDefinition(R, OS); > > - for (auto ai : Args) { > + for (auto const &ai : Args) { > ai->writeAccessors(OS); > OS << "\n\n"; > > if (ai->isEnumArg()) > - static_cast<EnumArgument *>(ai)->writeConversion(OS); > + static_cast<const EnumArgument *>(ai.get())->writeConversion(OS); > else if (ai->isVariadicEnumArg()) > - static_cast<VariadicEnumArgument *>(ai)->writeConversion(OS); > + static_cast<const VariadicEnumArgument *>(ai.get()) > + ->writeConversion(OS); > } > > OS << R.getValueAsString("AdditionalMembers"); > @@ -1548,19 +1551,19 @@ void EmitClangAttrImpl(RecordKeeper &Rec > > if (!R.getValueAsBit("ASTNode")) > continue; > - > + > std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); > - std::vector<Argument*> Args; > + std::vector<std::unique_ptr<Argument>> Args; > for (auto ri : ArgRecords) > - Args.push_back(createArgument(*ri, R.getName())); > + Args.emplace_back(createArgument(*ri, R.getName())); > > - for (auto ai : Args) > + for (auto const &ai : Args) > ai->writeAccessorDefinitions(OS); > > OS << R.getName() << "Attr *" << R.getName() > << "Attr::clone(ASTContext &C) const {\n"; > OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; > - for (auto ai : Args) { > + for (auto const &ai : Args) { > OS << ", "; > ai->writeCloneArgs(OS); > } > @@ -1651,7 +1654,7 @@ void EmitClangAttrPCHRead(RecordKeeper & > Record *InhClass = Records.getClass("InheritableAttr"); > std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), > ArgRecords; > - std::vector<Argument*> Args; > + std::vector<std::unique_ptr<Argument>> Args; > > OS << " switch (Kind) {\n"; > OS << " default:\n"; > @@ -1670,12 +1673,11 @@ void EmitClangAttrPCHRead(RecordKeeper & > ArgRecords = R.getValueAsListOfDefs("Args"); > Args.clear(); > for (auto ai : ArgRecords) { > - Argument *A = createArgument(*ai, R.getName()); > - Args.push_back(A); > - A->writePCHReadDecls(OS); > + Args.emplace_back(createArgument(*ai, R.getName())); > + Args.back()->writePCHReadDecls(OS); > } > OS << " New = new (Context) " << R.getName() << "Attr(Range, Context"; > - for (auto ri : Args) { > + for (auto const &ri : Args) { > OS << ", "; > ri->writePCHReadArgs(OS); > } > @@ -1846,12 +1848,8 @@ void EmitClangAttrASTVisitor(RecordKeepe > << " return false;\n"; > > std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); > - for (auto ri : ArgRecords) { > - Record &ArgRecord = *ri; > - Argument *Arg = createArgument(ArgRecord, R.getName()); > - assert(Arg); > - Arg->writeASTVisitorTraversal(OS); > - } > + for (auto ri : ArgRecords) > + createArgument(*ri, R.getName())->writeASTVisitorTraversal(OS); > > OS << " return true;\n"; > OS << "}\n\n"; > @@ -1921,20 +1919,17 @@ void EmitClangAttrTemplateInstantiate(Re > } > > std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); > - std::vector<Argument*> Args; > + std::vector<std::unique_ptr<Argument>> Args; > Args.reserve(ArgRecords.size()); > > - for (auto ArgRecord : ArgRecords) { > - Argument *Arg = createArgument(*ArgRecord, R.getName()); > - assert(Arg); > - Args.push_back(Arg); > - } > + for (auto ArgRecord : ArgRecords) > + Args.emplace_back(createArgument(*ArgRecord, R.getName())); > > - for (auto ai : Args) { > + for (auto const &ai : Args) > ai->writeTemplateInstantiation(OS); > - } > + > OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), > C"; > - for (auto ai : Args) { > + for (auto const &ai : Args) { > OS << ", "; > ai->writeTemplateInstantiationArgs(OS); > } > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
