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 17using 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? 21static 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 NULL; 31} 32 33void 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 56void StmtIteratorBase::NextDecl(bool ImmediateAdvance) { 57 assert (getVAPtr() == NULL); 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 70bool 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 95StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) 96 : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { 97 NextDecl(false); 98} 99 100StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) 101 : stmt(0), DGI(0), RawVAPtr(SizeOfTypeVAMode) { 102 RawVAPtr |= reinterpret_cast<uintptr_t>(t); 103} 104 105Stmt*& 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