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