Add StmtIterator support for DeclGroups.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57271 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index c652ef2..64e8920 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -21,21 +21,32 @@
class Stmt;
class ScopedDecl;
+class Decl;
class VariableArrayType;
class StmtIteratorBase {
protected:
- enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, Flags = 0x3 };
+ enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3,
+ Flags = 0x3 };
- union { Stmt** stmt; ScopedDecl* decl; };
- uintptr_t RawVAPtr;
+ union { Stmt** stmt; ScopedDecl* decl; Decl** DGI; };
+ uintptr_t RawVAPtr;
+ Decl** DGE;
bool inDecl() const {
- return RawVAPtr & DeclMode ? true : false;
+ return (RawVAPtr & Flags) == DeclMode;
+ }
+
+ bool inDeclGroup() const {
+ return (RawVAPtr & Flags) == DeclGroupMode;
}
bool inSizeOfTypeVA() const {
- return RawVAPtr & SizeOfTypeVAMode ? true : false;
+ return (RawVAPtr & Flags) == SizeOfTypeVAMode;
+ }
+
+ bool inStmt() const {
+ return (RawVAPtr & Flags) == 0;
}
VariableArrayType* getVAPtr() const {
@@ -43,11 +54,12 @@
}
void setVAPtr(VariableArrayType* P) {
- assert (inDecl() || inSizeOfTypeVA());
+ assert (inDecl() || inDeclGroup() || inSizeOfTypeVA());
RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
}
void NextDecl(bool ImmediateAdvance = true);
+ bool HandleDecl(Decl* D);
void NextVA();
Stmt*& GetDeclExpr() const;
@@ -55,6 +67,7 @@
StmtIteratorBase(Stmt** s) : stmt(s), RawVAPtr(0) {}
StmtIteratorBase(ScopedDecl* d);
StmtIteratorBase(VariableArrayType* t);
+ StmtIteratorBase(Decl** dgi, Decl** dge);
StmtIteratorBase() : stmt(NULL), RawVAPtr(0) {}
};
@@ -69,16 +82,17 @@
public:
StmtIteratorImpl() {}
StmtIteratorImpl(Stmt** s) : StmtIteratorBase(s) {}
+ StmtIteratorImpl(Decl** dgi, Decl** dge) : StmtIteratorBase(dgi, dge) {}
StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {}
StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {}
DERIVED& operator++() {
- if (inDecl()) {
+ if (inDecl() || inDeclGroup()) {
if (getVAPtr()) NextVA();
else NextDecl();
}
else if (inSizeOfTypeVA())
- NextVA();
+ NextVA();
else
++stmt;
@@ -100,7 +114,7 @@
}
REFERENCE operator*() const {
- return (REFERENCE) (inDecl() || inSizeOfTypeVA() ? GetDeclExpr() : *stmt);
+ return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr());
}
REFERENCE operator->() const { return operator*(); }
@@ -110,7 +124,9 @@
explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
-
+ StmtIterator(Decl** dgi, Decl** dge)
+ : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
+
StmtIterator(VariableArrayType* t):StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
StmtIterator(ScopedDecl* D) : StmtIteratorImpl<StmtIterator,Stmt*&>(D) {}
};
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 3af66b3..1b0e9d5 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -35,12 +35,21 @@
p = FindVA(p->getElementType().getTypePtr());
setVAPtr(p);
- if (!p && inDecl()) {
- if (VarDecl* VD = dyn_cast<VarDecl>(decl))
- if (VD->Init)
- return;
+ if (!p) {
+ if (inDecl()) {
+ if (VarDecl* VD = dyn_cast<VarDecl>(decl))
+ if (VD->Init)
+ return;
- NextDecl();
+ NextDecl();
+ }
+ else if (inDeclGroup()) {
+ if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
+ if (VD->Init)
+ return;
+
+ NextDecl();
+ }
} else if (inSizeOfTypeVA()) {
assert(!decl);
RawVAPtr = 0;
@@ -48,45 +57,56 @@
}
void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
- assert (inDecl());
assert (getVAPtr() == NULL);
- assert (decl);
- if (ImmediateAdvance) {
- decl = decl->getNextDeclarator();
+ if (inDecl()) {
+ assert (decl);
+
+ if (ImmediateAdvance)
+ decl = decl->getNextDeclarator();
+
+ for ( ; decl ; decl = decl->getNextDeclarator())
+ if (HandleDecl(decl))
+ return;
+ }
+ else {
+ assert (inDeclGroup());
+
+ if (ImmediateAdvance)
+ ++DGI;
+
+ for ( ; DGI != DGE; ++DGI)
+ if (HandleDecl(*DGI))
+ return;
+ }
- if (!decl) {
- RawVAPtr = 0;
- return;
+ RawVAPtr = 0;
+}
+
+bool StmtIteratorBase::HandleDecl(Decl* D) {
+
+ if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
+ if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
+ setVAPtr(VAPtr);
+ return true;
}
- }
-
- for ( ; decl ; decl = decl->getNextDeclarator()) {
- if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
- if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
- setVAPtr(VAPtr);
- return;
- }
-
- if (VD->getInit())
- return;
- }
- else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(decl)) {
- if (VariableArrayType* VAPtr =
- FindVA(TD->getUnderlyingType().getTypePtr())) {
- setVAPtr(VAPtr);
- return;
- }
- }
- else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(decl))
- if (ECD->getInitExpr())
- return;
+
+ if (VD->getInit())
+ return true;
}
-
- if (!decl) {
- RawVAPtr = 0;
- return;
+ else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(D)) {
+ if (VariableArrayType* VAPtr =
+ FindVA(TD->getUnderlyingType().getTypePtr())) {
+ setVAPtr(VAPtr);
+ return true;
+ }
}
+ else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
+ if (ECD->getInitExpr())
+ return true;
+ }
+
+ return false;
}
StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
@@ -95,16 +115,31 @@
NextDecl(false);
}
+StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
+ : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
+ NextDecl(false);
+}
+
StmtIteratorBase::StmtIteratorBase(VariableArrayType* t)
-: decl(NULL), RawVAPtr(SizeOfTypeVAMode) {
+: decl(0), RawVAPtr(SizeOfTypeVAMode) {
RawVAPtr |= reinterpret_cast<uintptr_t>(t);
}
Stmt*& StmtIteratorBase::GetDeclExpr() const {
+
+ if (inDeclGroup()) {
+ VarDecl* VD = cast<VarDecl>(*DGI);
+ return VD->Init;
+ }
+
+ assert (inDecl() || inSizeOfTypeVA());
+
if (VariableArrayType* VAPtr = getVAPtr()) {
assert (VAPtr->SizeExpr);
return VAPtr->SizeExpr;
}
+
+ assert (inDecl());
if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
assert (VD->Init);