[cfe-commits] r159925 - in /cfe/trunk: 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

Alexander Kornienko alexfh at google.com
Mon Jul 9 03:04:07 PDT 2012


Author: alexfh
Date: Mon Jul  9 05:04:07 2012
New Revision: 159925

URL: http://llvm.org/viewvc/llvm-project?rev=159925&view=rev
Log:
Inline storage of attributes in AttributedStmt.

Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/SemaStmtAttr.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Mon Jul  9 05:04:07 2012
@@ -149,8 +149,10 @@
 
 /// 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 @@
   /// 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 @@
   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 @@
   }
 };
 
-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;

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Mon Jul  9 05:04:07 2012
@@ -797,24 +797,32 @@
 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; }
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul  9 05:04:07 2012
@@ -2467,7 +2467,8 @@
   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,

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Mon Jul  9 05:04:07 2012
@@ -427,7 +427,7 @@
   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();

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Mon Jul  9 05:04:07 2012
@@ -273,6 +273,23 @@
   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)

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Jul  9 05:04:07 2012
@@ -173,9 +173,9 @@
 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;

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Mon Jul  9 05:04:07 2012
@@ -370,12 +370,10 @@
 }
 
 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);
 }
 

Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Mon Jul  9 05:04:07 2012
@@ -61,7 +61,7 @@
 
 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);

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jul  9 05:04:07 2012
@@ -1050,7 +1050,8 @@
   ///
   /// 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);
   }

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Jul  9 05:04:07 2012
@@ -162,9 +162,12 @@
 
 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 @@
       break;
 
     case STMT_ATTRIBUTED:
-      S = new (Context) AttributedStmt(Empty);
+      S = AttributedStmt::CreateEmpty(
+        Context,
+        /*NumAttrs*/Record[ASTStmtReader::NumStmtFields]);
       break;
 
     case STMT_IF:

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Jul  9 05:04:07 2012
@@ -3086,10 +3086,12 @@
 //===----------------------------------------------------------------------===//
 
 /// \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);
 

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Jul  9 05:04:07 2012
@@ -151,7 +151,8 @@
   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());

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=159925&r1=159924&r2=159925&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Jul  9 05:04:07 2012
@@ -109,6 +109,7 @@
 
 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);





More information about the cfe-commits mailing list