From: Ted Kremenek Date: Tue, 7 Oct 2008 23:04:14 +0000 (+0000) Subject: Add StmtIterator support for DeclGroups. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e6d1203b3346147cee51a8a6d374f1867f2cd23;p=clang 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 c652ef2071..64e892007b 100644 --- a/include/clang/AST/StmtIterator.h +++ b/include/clang/AST/StmtIterator.h @@ -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; }; - 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 @@ protected: } void setVAPtr(VariableArrayType* P) { - assert (inDecl() || inSizeOfTypeVA()); + assert (inDecl() || inDeclGroup() || inSizeOfTypeVA()); RawVAPtr = reinterpret_cast(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,16 +82,17 @@ 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(); } else if (inSizeOfTypeVA()) - NextVA(); + NextVA(); else ++stmt; @@ -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,7 +124,9 @@ struct StmtIterator : public StmtIteratorImpl { explicit StmtIterator() : StmtIteratorImpl() {} StmtIterator(Stmt** S) : StmtIteratorImpl(S) {} - + StmtIterator(Decl** dgi, Decl** dge) + : StmtIteratorImpl(dgi, dge) {} + StmtIterator(VariableArrayType* t):StmtIteratorImpl(t) {} StmtIterator(ScopedDecl* D) : StmtIteratorImpl(D) {} }; diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp index 3af66b30bf..1b0e9d57c0 100644 --- a/lib/AST/StmtIterator.cpp +++ b/lib/AST/StmtIterator.cpp @@ -35,12 +35,21 @@ void StmtIteratorBase::NextVA() { p = FindVA(p->getElementType().getTypePtr()); setVAPtr(p); - if (!p && inDecl()) { - if (VarDecl* VD = dyn_cast(decl)) - if (VD->Init) - return; + if (!p) { + if (inDecl()) { + if (VarDecl* VD = dyn_cast(decl)) + if (VD->Init) + return; + + NextDecl(); + } + else if (inDeclGroup()) { + if (VarDecl* VD = dyn_cast(*DGI)) + if (VD->Init) + return; - NextDecl(); + 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); - assert (decl); - - if (ImmediateAdvance) { - decl = decl->getNextDeclarator(); - - if (!decl) { - RawVAPtr = 0; - return; - } - } - for ( ; decl ; decl = decl->getNextDeclarator()) { - if (VarDecl* VD = dyn_cast(decl)) { - if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { - setVAPtr(VAPtr); + if (inDecl()) { + assert (decl); + + if (ImmediateAdvance) + decl = decl->getNextDeclarator(); + + for ( ; decl ; decl = decl->getNextDeclarator()) + if (HandleDecl(decl)) return; - } - - if (VD->getInit()) - return; - } - else if (TypedefDecl* TD = dyn_cast(decl)) { - if (VariableArrayType* VAPtr = - FindVA(TD->getUnderlyingType().getTypePtr())) { - setVAPtr(VAPtr); + } + else { + assert (inDeclGroup()); + + if (ImmediateAdvance) + ++DGI; + + for ( ; DGI != DGE; ++DGI) + if (HandleDecl(*DGI)) return; - } + } + + RawVAPtr = 0; +} + +bool StmtIteratorBase::HandleDecl(Decl* D) { + + if (VarDecl* VD = dyn_cast(D)) { + if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { + setVAPtr(VAPtr); + return true; } - else if (EnumConstantDecl* ECD = dyn_cast(decl)) - if (ECD->getInitExpr()) - return; + + if (VD->getInit()) + return true; } - - if (!decl) { - RawVAPtr = 0; - return; + else if (TypedefDecl* TD = dyn_cast(D)) { + if (VariableArrayType* VAPtr = + FindVA(TD->getUnderlyingType().getTypePtr())) { + setVAPtr(VAPtr); + return true; + } + } + else if (EnumConstantDecl* ECD = dyn_cast(D)) { + if (ECD->getInitExpr()) + return true; } + + return false; } StmtIteratorBase::StmtIteratorBase(ScopedDecl* d) @@ -95,16 +115,31 @@ 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(t); } Stmt*& StmtIteratorBase::GetDeclExpr() const { + + if (inDeclGroup()) { + VarDecl* VD = cast(*DGI); + return VD->Init; + } + + assert (inDecl() || inSizeOfTypeVA()); + if (VariableArrayType* VAPtr = getVAPtr()) { assert (VAPtr->SizeExpr); return VAPtr->SizeExpr; } + + assert (inDecl()); if (VarDecl* VD = dyn_cast(decl)) { assert (VD->Init);