Add StmtIterator support for DeclGroups.

llvm-svn: 57271
This commit is contained in:
Ted Kremenek 2008-10-07 23:04:14 +00:00
parent 60ad173dfe
commit f9638bac59
2 changed files with 100 additions and 49 deletions

View File

@ -21,21 +21,32 @@ namespace clang {
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; };
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 @@ protected:
}
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 @@ protected:
StmtIteratorBase(Stmt** s) : stmt(s), RawVAPtr(0) {}
StmtIteratorBase(ScopedDecl* d);
StmtIteratorBase(VariableArrayType* t);
StmtIteratorBase(Decl** dgi, Decl** dge);
StmtIteratorBase() : stmt(NULL), RawVAPtr(0) {}
};
@ -69,11 +82,12 @@ protected:
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();
}
@ -100,7 +114,7 @@ public:
}
REFERENCE operator*() const {
return (REFERENCE) (inDecl() || inSizeOfTypeVA() ? GetDeclExpr() : *stmt);
return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr());
}
REFERENCE operator->() const { return operator*(); }
@ -110,6 +124,8 @@ struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
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) {}

View File

@ -35,12 +35,21 @@ void StmtIteratorBase::NextVA() {
p = FindVA(p->getElementType().getTypePtr());
setVAPtr(p);
if (!p && inDecl()) {
if (!p) {
if (inDecl()) {
if (VarDecl* VD = dyn_cast<VarDecl>(decl))
if (VD->Init)
return;
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::NextVA() {
}
void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
assert (inDecl());
assert (getVAPtr() == NULL);
if (inDecl()) {
assert (decl);
if (ImmediateAdvance) {
if (ImmediateAdvance)
decl = decl->getNextDeclarator();
if (!decl) {
RawVAPtr = 0;
for ( ; decl ; decl = decl->getNextDeclarator())
if (HandleDecl(decl))
return;
}
else {
assert (inDeclGroup());
if (ImmediateAdvance)
++DGI;
for ( ; DGI != DGE; ++DGI)
if (HandleDecl(*DGI))
return;
}
for ( ; decl ; decl = decl->getNextDeclarator()) {
if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
RawVAPtr = 0;
}
bool StmtIteratorBase::HandleDecl(Decl* D) {
if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
setVAPtr(VAPtr);
return;
return true;
}
if (VD->getInit())
return;
return true;
}
else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(decl)) {
else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(D)) {
if (VariableArrayType* VAPtr =
FindVA(TD->getUnderlyingType().getTypePtr())) {
setVAPtr(VAPtr);
return;
return true;
}
}
else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(decl))
else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
if (ECD->getInitExpr())
return;
return true;
}
if (!decl) {
RawVAPtr = 0;
return;
}
return false;
}
StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
@ -95,17 +115,32 @@ StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
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);
return VD->Init;