]> granicus.if.org Git - clang/commitdiff
Inline storage of attributes in AttributedStmt.
authorAlexander Kornienko <alexfh@google.com>
Mon, 9 Jul 2012 10:04:07 +0000 (10:04 +0000)
committerAlexander Kornienko <alexfh@google.com>
Mon, 9 Jul 2012 10:04:07 +0000 (10:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159925 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/clang/AST/Attr.h
include/clang/AST/Stmt.h
include/clang/Sema/Sema.h
include/clang/Serialization/ASTWriter.h
lib/AST/Stmt.cpp
lib/AST/StmtPrinter.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/SemaStmtAttr.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriter.cpp
lib/Serialization/ASTWriterDecl.cpp
lib/Serialization/ASTWriterStmt.cpp

index 95841801b6267dad294b1d417ffe711889bc078c..27b44d4bd97b05d8debdd93e1b92215bba055e55 100644 (file)
@@ -149,8 +149,10 @@ typedef SmallVector<const Attr*, 2> ConstAttrVec;
 
 /// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
 /// providing attributes that are of a specifc type.
-template <typename SpecificAttr>
+template <typename SpecificAttr, typename Container = AttrVec>
 class specific_attr_iterator {
+  typedef typename Container::const_iterator Iterator;
+
   /// Current - The current, underlying iterator.
   /// In order to ensure we don't dereference an invalid iterator unless
   /// specifically requested, we don't necessarily advance this all the
@@ -158,14 +160,14 @@ class specific_attr_iterator {
   /// operation is acting on what should be a past-the-end iterator,
   /// then we offer no guarantees, but this way we do not dererence a
   /// past-the-end iterator when we move to a past-the-end position.
-  mutable AttrVec::const_iterator Current;
+  mutable Iterator Current;
 
   void AdvanceToNext() const {
     while (!isa<SpecificAttr>(*Current))
       ++Current;
   }
 
-  void AdvanceToNext(AttrVec::const_iterator I) const {
+  void AdvanceToNext(Iterator I) const {
     while (Current != I && !isa<SpecificAttr>(*Current))
       ++Current;
   }
@@ -178,7 +180,7 @@ public:
   typedef std::ptrdiff_t            difference_type;
 
   specific_attr_iterator() : Current() { }
-  explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { }
+  explicit specific_attr_iterator(Iterator i) : Current(i) { }
 
   reference operator*() const {
     AdvanceToNext();
@@ -213,23 +215,27 @@ public:
   }
 };
 
-template <typename T>
-inline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) {
-  return specific_attr_iterator<T>(vec.begin());
+template <typename SpecificAttr, typename Container>
+inline specific_attr_iterator<SpecificAttr, Container>
+          specific_attr_begin(const Container& container) {
+  return specific_attr_iterator<SpecificAttr, Container>(container.begin());
 }
-template <typename T>
-inline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) {
-  return specific_attr_iterator<T>(vec.end());
+template <typename SpecificAttr, typename Container>
+inline specific_attr_iterator<SpecificAttr, Container>
+          specific_attr_end(const Container& container) {
+  return specific_attr_iterator<SpecificAttr, Container>(container.end());
 }
 
-template <typename T>
-inline bool hasSpecificAttr(const AttrVec& vec) {
-  return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec);
+template <typename SpecificAttr, typename Container>
+inline bool hasSpecificAttr(const Container& container) {
+  return specific_attr_begin<SpecificAttr>(container) !=
+          specific_attr_end<SpecificAttr>(container);
 }
-template <typename T>
-inline T *getSpecificAttr(const AttrVec& vec) {
-  specific_attr_iterator<T> i = specific_attr_begin<T>(vec);
-  if (i != specific_attr_end<T>(vec))
+template <typename SpecificAttr, typename Container>
+inline SpecificAttr *getSpecificAttr(const Container& container) {
+  specific_attr_iterator<SpecificAttr, Container> i =
+      specific_attr_begin<SpecificAttr>(container);
+  if (i != specific_attr_end<SpecificAttr>(container))
     return *i;
   else
     return 0;
index 1662ba87b4c7b474c14a4e8b878200d85edb0820..14b28f8e3d894ea010d0e211d36c7cbfac16d105 100644 (file)
@@ -797,24 +797,32 @@ public:
 class AttributedStmt : public Stmt {
   Stmt *SubStmt;
   SourceLocation AttrLoc;
-  AttrVec Attrs;
-  // TODO: It can be done as Attr *Attrs[1]; and variable size array as in
-  // StringLiteral
+  unsigned NumAttrs;
+  const Attr *Attrs[1];
 
   friend class ASTStmtReader;
 
-public:
-  AttributedStmt(SourceLocation loc, const AttrVec &attrs, Stmt *substmt)
-    : Stmt(AttributedStmtClass), SubStmt(substmt), AttrLoc(loc), Attrs(attrs) {
+  AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
+    : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
+      NumAttrs(Attrs.size()) {
+    memcpy(this->Attrs, Attrs.data(), Attrs.size() * sizeof(Attr*));
   }
 
-  // \brief Build an empty attributed statement.
-  explicit AttributedStmt(EmptyShell Empty)
-    : Stmt(AttributedStmtClass, Empty) {
+  explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
+    : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
+    memset(Attrs, 0, NumAttrs * sizeof(Attr*));
   }
 
+public:
+  static AttributedStmt *Create(ASTContext &C, SourceLocation Loc,
+                                ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
+  // \brief Build an empty attributed statement.
+  static AttributedStmt *CreateEmpty(ASTContext &C, unsigned NumAttrs);
+
   SourceLocation getAttrLoc() const { return AttrLoc; }
-  const AttrVec &getAttrs() const { return Attrs; }
+  ArrayRef<const Attr*> getAttrs() const {
+    return ArrayRef<const Attr*>(Attrs, NumAttrs);
+  }
   Stmt *getSubStmt() { return SubStmt; }
   const Stmt *getSubStmt() const { return SubStmt; }
 
index c1d0d63819bdd1dcba849d379542ae7008e0e60c..a48cde03ba6c061a6707e53f99d365e755f08898 100644 (file)
@@ -2467,7 +2467,8 @@ public:
   StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
                             SourceLocation ColonLoc, Stmt *SubStmt);
 
-  StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, const AttrVec &Attrs,
+  StmtResult ActOnAttributedStmt(SourceLocation AttrLoc,
+                                 ArrayRef<const Attr*> Attrs,
                                  Stmt *SubStmt);
 
   StmtResult ActOnIfStmt(SourceLocation IfLoc,
index 830a163eedc0226ce9054cd787d498dbb7339791..d038d58aed8bb79f0866ee6e878f783cc382252a 100644 (file)
@@ -427,7 +427,7 @@ private:
   void WriteReferencedSelectorsPool(Sema &SemaRef);
   void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
                             bool IsModule);
-  void WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record);
+  void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
   void ResolveDeclUpdatesBlocks();
   void WriteDeclUpdatesBlocks();
   void WriteDeclReplacementsBlock();
index b6bb5282204b5ec09f6ef19e8bd8d3827c27c9e7..ff6374c2d8ecc09c41d013df4f6e18f92ab5bb99 100644 (file)
@@ -273,6 +273,23 @@ const char *LabelStmt::getName() const {
   return getDecl()->getIdentifier()->getNameStart();
 }
 
+AttributedStmt *AttributedStmt::Create(ASTContext &C, SourceLocation Loc,
+                                       ArrayRef<const Attr*> Attrs,
+                                       Stmt *SubStmt) {
+  void *Mem = C.Allocate(sizeof(AttributedStmt) +
+                         sizeof(Attr*) * (Attrs.size() - 1),
+                         llvm::alignOf<AttributedStmt>());
+  return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
+}
+
+AttributedStmt *AttributedStmt::CreateEmpty(ASTContext &C, unsigned NumAttrs) {
+  assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
+  void *Mem = C.Allocate(sizeof(AttributedStmt) +
+                         sizeof(Attr*) * (NumAttrs - 1),
+                         llvm::alignOf<AttributedStmt>());
+  return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
+}
+
 // This is defined here to avoid polluting Stmt.h with importing Expr.h
 SourceRange ReturnStmt::getSourceRange() const {
   if (RetExpr)
index 8b989e6ae38cf211b39f4b26e19203fd0677a386..2f7cb55c7cc1008adf6aad850d1431dc898d6faa 100644 (file)
@@ -173,9 +173,9 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
 void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
   OS << "[[";
   bool first = true;
-  for (AttrVec::const_iterator it = Node->getAttrs().begin(),
-                               end = Node->getAttrs().end();
-                               it != end; ++it) {
+  for (ArrayRef<const Attr*>::iterator it = Node->getAttrs().begin(),
+                                       end = Node->getAttrs().end();
+                                       it != end; ++it) {
     if (!first) {
       OS << ", ";
       first = false;
index 2db8b5da63096601d6acadfc6e336c8106c2dfbe..9be1d34dae7aac0a1a44c7e098303ef93124ce76 100644 (file)
@@ -370,12 +370,10 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
 }
 
 StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc,
-                                     const AttrVec &Attrs,
+                                     ArrayRef<const Attr*> Attrs,
                                      Stmt *SubStmt) {
-  // Fill in the declaration and return it. Variable length will require to
-  // change this to AttributedStmt::Create(Context, ....);
-  // and probably using ArrayRef
-  AttributedStmt *LS = new (Context) AttributedStmt(AttrLoc, Attrs, SubStmt);
+  // Fill in the declaration and return it.
+  AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt);
   return Owned(LS);
 }
 
index 395b9d6259604376dc368ac22842586c2a055821..3c15b7a8afadcfb65f654cbeb32d858fe6be99e5 100644 (file)
@@ -61,7 +61,7 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
 
 StmtResult Sema::ProcessStmtAttributes(Stmt *S, AttributeList *AttrList,
                                        SourceRange Range) {
-  AttrVec Attrs;
+  SmallVector<const Attr*, 8> Attrs;
   for (const AttributeList* l = AttrList; l; l = l->getNext()) {
     if (Attr *a = ProcessStmtAttribute(*this, S, *l, Range))
       Attrs.push_back(a);
index 3b41f758d9d6a56ea8d17ecc88ad19549990c2e3..b03f86bb0ed7cb641ee588837c1e677d17838005 100644 (file)
@@ -1050,7 +1050,8 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, const AttrVec &Attrs,
+  StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
+                                   ArrayRef<const Attr*> Attrs,
                                    Stmt *SubStmt) {
     return SemaRef.ActOnAttributedStmt(AttrLoc, Attrs, SubStmt);
   }
index 460841b2ff073095cef9a8f6a19e287978a95d4d..7d56f10eb5382b20f5251f0107276f235bf8fffe 100644 (file)
@@ -162,9 +162,12 @@ void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
 
 void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) {
   VisitStmt(S);
+  uint64_t NumAttrs = Record[Idx++];
   AttrVec Attrs;
   Reader.ReadAttributes(F, Attrs, Record, Idx);
-  S->Attrs = Attrs;
+  assert(NumAttrs == S->NumAttrs);
+  assert(NumAttrs == Attrs.size());
+  std::copy(Attrs.begin(), Attrs.end(), S->Attrs);
   S->SubStmt = Reader.ReadSubStmt();
   S->AttrLoc = ReadSourceLocation(Record, Idx);
 }
@@ -1648,7 +1651,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case STMT_ATTRIBUTED:
-      S = new (Context) AttributedStmt(Empty);
+      S = AttributedStmt::CreateEmpty(
+        Context,
+        /*NumAttrs*/Record[ASTStmtReader::NumStmtFields]);
       break;
 
     case STMT_IF:
index 566c8b77f5e7ba425b98ffbea733613ee15d2eaf..6a6863f17bf076325d2df742e6a4d1d4168daa36 100644 (file)
@@ -3086,10 +3086,12 @@ void ASTWriter::WriteMergedDecls() {
 //===----------------------------------------------------------------------===//
 
 /// \brief Write a record containing the given attributes.
-void ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) {
+void ASTWriter::WriteAttributes(ArrayRef<const Attr*> Attrs,
+                                RecordDataImpl &Record) {
   Record.push_back(Attrs.size());
-  for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){
-    const Attr * A = *i;
+  for (ArrayRef<const Attr *>::iterator i = Attrs.begin(),
+                                        e = Attrs.end(); i != e; ++i){
+    const Attr *A = *i;
     Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs
     AddSourceRange(A->getRange(), Record);
 
index d4ebc1c42a108b7db2d813ea116453817ce77eb9..96b602221ebdb8052270ddf060774890d51f75fb 100644 (file)
@@ -151,7 +151,8 @@ void ASTDeclWriter::VisitDecl(Decl *D) {
   Record.push_back(D->isInvalidDecl());
   Record.push_back(D->hasAttrs());
   if (D->hasAttrs())
-    Writer.WriteAttributes(D->getAttrs(), Record);
+    Writer.WriteAttributes(ArrayRef<const Attr*>(D->getAttrs().begin(),
+                                                 D->getAttrs().size()), Record);
   Record.push_back(D->isImplicit());
   Record.push_back(D->isUsed(false));
   Record.push_back(D->isReferenced());
index aa24962b66485f739485756d64d9165a428f8065..f63388fa2fd17def153fd6bed53c49ebf88fa4ec 100644 (file)
@@ -109,6 +109,7 @@ void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
 
 void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
   VisitStmt(S);
+  Record.push_back(S->getAttrs().size());
   Writer.WriteAttributes(S->getAttrs(), Record);
   Writer.AddStmt(S->getSubStmt());
   Writer.AddSourceLocation(S->getAttrLoc(), Record);