aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2012-07-09 10:04:07 +0000
committerAlexander Kornienko <alexfh@google.com>2012-07-09 10:04:07 +0000
commit4990890fc9428f98bef90ba349203a648c592778 (patch)
tree9c2fcfee3f7fb584462952bf667caaffa7fa44ed
parentef0ebee9a4e1e6254b9c54c6fbb30045ed959c37 (diff)
Inline storage of attributes in AttributedStmt.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159925 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Attr.h40
-rw-r--r--include/clang/AST/Stmt.h28
-rw-r--r--include/clang/Sema/Sema.h3
-rw-r--r--include/clang/Serialization/ASTWriter.h2
-rw-r--r--lib/AST/Stmt.cpp17
-rw-r--r--lib/AST/StmtPrinter.cpp6
-rw-r--r--lib/Sema/SemaStmt.cpp8
-rw-r--r--lib/Sema/SemaStmtAttr.cpp2
-rw-r--r--lib/Sema/TreeTransform.h3
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp9
-rw-r--r--lib/Serialization/ASTWriter.cpp8
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp3
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp1
13 files changed, 85 insertions, 45 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 95841801b6..27b44d4bd9 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -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;
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 1662ba87b4..14b28f8e3d 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -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; }
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index c1d0d63819..a48cde03ba 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -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,
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 830a163eed..d038d58aed 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -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();
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index b6bb528220..ff6374c2d8 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -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)
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 8b989e6ae3..2f7cb55c7c 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -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;
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 2db8b5da63..9be1d34dae 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -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);
}
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index 395b9d6259..3c15b7a8af 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -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);
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 3b41f758d9..b03f86bb0e 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -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);
}
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 460841b2ff..7d56f10eb5 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -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:
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 566c8b77f5..6a6863f17b 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -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);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index d4ebc1c42a..96b602221e 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -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());
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index aa24962b66..f63388fa2f 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -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);