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