r202989 - [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).

Aaron Ballman aaron at aaronballman.com
Wed Mar 5 08:49:55 PST 2014


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);
     }





More information about the cfe-commits mailing list