]> granicus.if.org Git - clang/commitdiff
[AST] Inline CompoundStmt contents into the parent allocation.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 24 Dec 2017 16:24:20 +0000 (16:24 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 24 Dec 2017 16:24:20 +0000 (16:24 +0000)
Saves a pointer on every CompoundStmt.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321429 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Stmt.h
lib/AST/ASTImporter.cpp
lib/AST/Stmt.cpp
lib/Analysis/BodyFarm.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaStmt.cpp
lib/Serialization/ASTReaderStmt.cpp

index d470392e1afe1b561262a993dfec2e95eae50d9e..b27dbfacf6a6433a536aecd9b0261ac220cd98f0 100644 (file)
@@ -592,15 +592,21 @@ public:
 };
 
 /// CompoundStmt - This represents a group of statements like { stmt stmt }.
-class CompoundStmt : public Stmt {
+class CompoundStmt final : public Stmt,
+                           private llvm::TrailingObjects<CompoundStmt, Stmt *> {
   friend class ASTStmtReader;
+  friend TrailingObjects;
 
-  Stmt** Body = nullptr;
   SourceLocation LBraceLoc, RBraceLoc;
 
+  CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB, SourceLocation RB);
+  explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
+
+  void setStmts(ArrayRef<Stmt *> Stmts);
+
 public:
-  CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
-               SourceLocation LB, SourceLocation RB);
+  static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
+                              SourceLocation LB, SourceLocation RB);
 
   // \brief Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
@@ -609,11 +615,7 @@ public:
   }
 
   // \brief Build an empty compound statement.
-  explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {
-    CompoundStmtBits.NumStmts = 0;
-  }
-
-  void setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts);
+  static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts);
 
   bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
   unsigned size() const { return CompoundStmtBits.NumStmts; }
@@ -622,14 +624,16 @@ public:
   using body_range = llvm::iterator_range<body_iterator>;
 
   body_range body() { return body_range(body_begin(), body_end()); }
-  body_iterator body_begin() { return Body; }
-  body_iterator body_end() { return Body + size(); }
-  Stmt *body_front() { return !body_empty() ? Body[0] : nullptr; }
-  Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; }
+  body_iterator body_begin() { return getTrailingObjects<Stmt *>(); }
+  body_iterator body_end() { return body_begin() + size(); }
+  Stmt *body_front() { return !body_empty() ? body_begin()[0] : nullptr; }
+  Stmt *body_back() {
+    return !body_empty() ? body_begin()[size() - 1] : nullptr;
+  }
 
   void setLastStmt(Stmt *S) {
     assert(!body_empty() && "setLastStmt");
-    Body[size()-1] = S;
+    body_begin()[size() - 1] = S;
   }
 
   using const_body_iterator = Stmt* const *;
@@ -639,15 +643,17 @@ public:
     return body_const_range(body_begin(), body_end());
   }
 
-  const_body_iterator body_begin() const { return Body; }
-  const_body_iterator body_end() const { return Body + size(); }
+  const_body_iterator body_begin() const {
+    return getTrailingObjects<Stmt *>();
+  }
+  const_body_iterator body_end() const { return body_begin() + size(); }
 
   const Stmt *body_front() const {
-    return !body_empty() ? Body[0] : nullptr;
+    return !body_empty() ? body_begin()[0] : nullptr;
   }
 
   const Stmt *body_back() const {
-    return !body_empty() ? Body[size() - 1] : nullptr;
+    return !body_empty() ? body_begin()[size() - 1] : nullptr;
   }
 
   using reverse_body_iterator = std::reverse_iterator<body_iterator>;
@@ -682,13 +688,10 @@ public:
   }
 
   // Iterators
-  child_range children() {
-    return child_range(Body, Body + CompoundStmtBits.NumStmts);
-  }
+  child_range children() { return child_range(body_begin(), body_end()); }
 
   const_child_range children() const {
-    return const_child_range(child_iterator(Body),
-                             child_iterator(Body + CompoundStmtBits.NumStmts));
+    return const_child_range(body_begin(), body_end());
   }
 };
 
index 0e627f9737ceb0482b1be5440729658808e920b9..5b46848bd07474ed638b15bbbf924aa8b9a54f95 100644 (file)
@@ -4321,9 +4321,8 @@ Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
 
   SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
   SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
-  return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(),
-                                                    ToStmts,
-                                                    ToLBraceLoc, ToRBraceLoc);
+  return CompoundStmt::Create(Importer.getToContext(), ToStmts, ToLBraceLoc,
+                              ToRBraceLoc);
 }
 
 Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
index 773b4da940b860e98354899466e51e136fcc3640..982fd458493fced3d10f633cb030f4822ec75748 100644 (file)
@@ -299,31 +299,34 @@ SourceLocation Stmt::getLocEnd() const {
   llvm_unreachable("unknown statement kind");
 }
 
-CompoundStmt::CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
-                           SourceLocation LB, SourceLocation RB)
-  : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
+CompoundStmt::CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB,
+                           SourceLocation RB)
+    : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
   CompoundStmtBits.NumStmts = Stmts.size();
+  setStmts(Stmts);
+}
+
+void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {
   assert(CompoundStmtBits.NumStmts == Stmts.size() &&
          "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
 
-  if (Stmts.empty()) {
-    Body = nullptr;
-    return;
-  }
-
-  Body = new (C) Stmt*[Stmts.size()];
-  std::copy(Stmts.begin(), Stmts.end(), Body);
+  std::copy(Stmts.begin(), Stmts.end(), body_begin());
 }
 
-void CompoundStmt::setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts) {
-  if (Body)
-    C.Deallocate(Body);
-  CompoundStmtBits.NumStmts = Stmts.size();
-  assert(CompoundStmtBits.NumStmts == Stmts.size() &&
-         "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
+CompoundStmt *CompoundStmt::Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
+                                   SourceLocation LB, SourceLocation RB) {
+  void *Mem =
+      C.Allocate(totalSizeToAlloc<Stmt *>(Stmts.size()), alignof(CompoundStmt));
+  return new (Mem) CompoundStmt(Stmts, LB, RB);
+}
 
-  Body = new (C) Stmt*[Stmts.size()];
-  std::copy(Stmts.begin(), Stmts.end(), Body);
+CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C,
+                                        unsigned NumStmts) {
+  void *Mem =
+      C.Allocate(totalSizeToAlloc<Stmt *>(NumStmts), alignof(CompoundStmt));
+  CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
+  New->CompoundStmtBits.NumStmts = NumStmts;
+  return New;
 }
 
 const char *LabelStmt::getName() const {
index e5d3c5ce5bc2a9b09ec00252ea6079e9ffe0598a..89ca8484819d181f3e3baed21090f36c2614fdd7 100644 (file)
@@ -133,7 +133,7 @@ BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
 }
 
 CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
-  return new (C) CompoundStmt(C, Stmts, SourceLocation(), SourceLocation());
+  return CompoundStmt::Create(C, Stmts, SourceLocation(), SourceLocation());
 }
 
 DeclRefExpr *ASTMaker::makeDeclRefExpr(
index f2fb95c39163b14bbf75b22c6873bd931fd311e6..aa26b37f444d9ec67a9b3e10947e7bd8fe198a6c 100644 (file)
@@ -12265,11 +12265,10 @@ void Sema::DefineImplicitLambdaToFunctionPointerConversion(
   // Construct the body of the conversion function { return __invoke; }.
   Expr *FunctionRef = BuildDeclRefExpr(Invoker, Invoker->getType(),
                                         VK_LValue, Conv->getLocation()).get();
-   assert(FunctionRef && "Can't refer to __invoke function?");
-   Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).get();
-   Conv->setBody(new (Context) CompoundStmt(Context, Return,
-                                            Conv->getLocation(),
-                                            Conv->getLocation()));
+  assert(FunctionRef && "Can't refer to __invoke function?");
+  Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).get();
+  Conv->setBody(CompoundStmt::Create(Context, Return, Conv->getLocation(),
+                                     Conv->getLocation()));
 
   Conv->markUsed(Context);
   Conv->setReferenced();
@@ -12330,9 +12329,8 @@ void Sema::DefineImplicitLambdaToBlockPointerConversion(
 
   // Set the body of the conversion function.
   Stmt *ReturnS = Return.get();
-  Conv->setBody(new (Context) CompoundStmt(Context, ReturnS,
-                                           Conv->getLocation(),
-                                           Conv->getLocation()));
+  Conv->setBody(CompoundStmt::Create(Context, ReturnS, Conv->getLocation(),
+                                     Conv->getLocation()));
   Conv->markUsed(Context);
 
   // We're done; notify the mutation listener, if any.
index 9c842ded1e101fd001b5bad389a92b15af4ab9d8..cff9fbbf491b2f68bbaa77c03e65daac19d7302f 100644 (file)
@@ -6265,9 +6265,8 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
   // a StmtExpr; currently this is only used for asm statements.
   // This is hacky, either create a new CXXStmtWithTemporaries statement or
   // a new AsmStmtWithTemporaries.
-  CompoundStmt *CompStmt = new (Context) CompoundStmt(Context, SubStmt,
-                                                      SourceLocation(),
-                                                      SourceLocation());
+  CompoundStmt *CompStmt = CompoundStmt::Create(
+      Context, SubStmt, SourceLocation(), SourceLocation());
   Expr *E = new (Context) StmtExpr(CompStmt, Context.VoidTy, SourceLocation(),
                                    SourceLocation());
   return MaybeCreateExprWithCleanups(E);
index ff0f4d99585127410693329f31803a292c96a650..4474d62949a24a7116af18a962c0c5a4a88401be 100644 (file)
@@ -388,7 +388,7 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
       DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
   }
 
-  return new (Context) CompoundStmt(Context, Elts, L, R);
+  return CompoundStmt::Create(Context, Elts, L, R);
 }
 
 StmtResult
index 8ef1491eb2da7307650e231ec798b6283fda2028..6163b811c7691d4aa9a5422fe6f86b50f682a472 100644 (file)
@@ -119,7 +119,7 @@ void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
   unsigned NumStmts = Record.readInt();
   while (NumStmts--)
     Stmts.push_back(Record.readSubStmt());
-  S->setStmts(Record.getContext(), Stmts);
+  S->setStmts(Stmts);
   S->LBraceLoc = ReadSourceLocation();
   S->RBraceLoc = ReadSourceLocation();
 }
@@ -3081,7 +3081,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case STMT_COMPOUND:
-      S = new (Context) CompoundStmt(Empty);
+      S = CompoundStmt::CreateEmpty(
+          Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields]);
       break;
 
     case STMT_CASE: