1*67e74705SXin Li //===--- StmtIterator.cpp - Iterators for Statements ------------------------===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // 10*67e74705SXin Li // This file defines internal methods for StmtIterator. 11*67e74705SXin Li // 12*67e74705SXin Li //===----------------------------------------------------------------------===// 13*67e74705SXin Li 14*67e74705SXin Li #include "clang/AST/StmtIterator.h" 15*67e74705SXin Li #include "clang/AST/Decl.h" 16*67e74705SXin Li 17*67e74705SXin Li using namespace clang; 18*67e74705SXin Li 19*67e74705SXin Li // FIXME: Add support for dependent-sized array types in C++? 20*67e74705SXin Li // Does it even make sense to build a CFG for an uninstantiated template? FindVA(const Type * t)21*67e74705SXin Listatic inline const VariableArrayType *FindVA(const Type* t) { 22*67e74705SXin Li while (const ArrayType *vt = dyn_cast<ArrayType>(t)) { 23*67e74705SXin Li if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt)) 24*67e74705SXin Li if (vat->getSizeExpr()) 25*67e74705SXin Li return vat; 26*67e74705SXin Li 27*67e74705SXin Li t = vt->getElementType().getTypePtr(); 28*67e74705SXin Li } 29*67e74705SXin Li 30*67e74705SXin Li return nullptr; 31*67e74705SXin Li } 32*67e74705SXin Li NextVA()33*67e74705SXin Livoid StmtIteratorBase::NextVA() { 34*67e74705SXin Li assert (getVAPtr()); 35*67e74705SXin Li 36*67e74705SXin Li const VariableArrayType *p = getVAPtr(); 37*67e74705SXin Li p = FindVA(p->getElementType().getTypePtr()); 38*67e74705SXin Li setVAPtr(p); 39*67e74705SXin Li 40*67e74705SXin Li if (p) 41*67e74705SXin Li return; 42*67e74705SXin Li 43*67e74705SXin Li if (inDeclGroup()) { 44*67e74705SXin Li if (VarDecl* VD = dyn_cast<VarDecl>(*DGI)) 45*67e74705SXin Li if (VD->hasInit()) 46*67e74705SXin Li return; 47*67e74705SXin Li 48*67e74705SXin Li NextDecl(); 49*67e74705SXin Li } 50*67e74705SXin Li else { 51*67e74705SXin Li assert(inSizeOfTypeVA()); 52*67e74705SXin Li RawVAPtr = 0; 53*67e74705SXin Li } 54*67e74705SXin Li } 55*67e74705SXin Li NextDecl(bool ImmediateAdvance)56*67e74705SXin Livoid StmtIteratorBase::NextDecl(bool ImmediateAdvance) { 57*67e74705SXin Li assert(getVAPtr() == nullptr); 58*67e74705SXin Li assert(inDeclGroup()); 59*67e74705SXin Li 60*67e74705SXin Li if (ImmediateAdvance) 61*67e74705SXin Li ++DGI; 62*67e74705SXin Li 63*67e74705SXin Li for ( ; DGI != DGE; ++DGI) 64*67e74705SXin Li if (HandleDecl(*DGI)) 65*67e74705SXin Li return; 66*67e74705SXin Li 67*67e74705SXin Li RawVAPtr = 0; 68*67e74705SXin Li } 69*67e74705SXin Li HandleDecl(Decl * D)70*67e74705SXin Libool StmtIteratorBase::HandleDecl(Decl* D) { 71*67e74705SXin Li if (VarDecl* VD = dyn_cast<VarDecl>(D)) { 72*67e74705SXin Li if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { 73*67e74705SXin Li setVAPtr(VAPtr); 74*67e74705SXin Li return true; 75*67e74705SXin Li } 76*67e74705SXin Li 77*67e74705SXin Li if (VD->getInit()) 78*67e74705SXin Li return true; 79*67e74705SXin Li } 80*67e74705SXin Li else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) { 81*67e74705SXin Li if (const VariableArrayType* VAPtr = 82*67e74705SXin Li FindVA(TD->getUnderlyingType().getTypePtr())) { 83*67e74705SXin Li setVAPtr(VAPtr); 84*67e74705SXin Li return true; 85*67e74705SXin Li } 86*67e74705SXin Li } 87*67e74705SXin Li else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) { 88*67e74705SXin Li if (ECD->getInitExpr()) 89*67e74705SXin Li return true; 90*67e74705SXin Li } 91*67e74705SXin Li 92*67e74705SXin Li return false; 93*67e74705SXin Li } 94*67e74705SXin Li StmtIteratorBase(Decl ** dgi,Decl ** dge)95*67e74705SXin LiStmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) 96*67e74705SXin Li : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { 97*67e74705SXin Li NextDecl(false); 98*67e74705SXin Li } 99*67e74705SXin Li StmtIteratorBase(const VariableArrayType * t)100*67e74705SXin LiStmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) 101*67e74705SXin Li : DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) { 102*67e74705SXin Li RawVAPtr |= reinterpret_cast<uintptr_t>(t); 103*67e74705SXin Li } 104*67e74705SXin Li GetDeclExpr() const105*67e74705SXin LiStmt*& StmtIteratorBase::GetDeclExpr() const { 106*67e74705SXin Li if (const VariableArrayType* VAPtr = getVAPtr()) { 107*67e74705SXin Li assert (VAPtr->SizeExpr); 108*67e74705SXin Li return const_cast<Stmt*&>(VAPtr->SizeExpr); 109*67e74705SXin Li } 110*67e74705SXin Li 111*67e74705SXin Li assert (inDeclGroup()); 112*67e74705SXin Li VarDecl* VD = cast<VarDecl>(*DGI); 113*67e74705SXin Li return *VD->getInitAddress(); 114*67e74705SXin Li } 115