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 (inDecl()) { 44 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) 45 if (VD->Init) 46 return; 47 48 NextDecl(); 49 } 50 else if (inDeclGroup()) { 51 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI)) 52 if (VD->Init) 53 return; 54 55 NextDecl(); 56 } 57 else { 58 assert (inSizeOfTypeVA()); 59 assert(!decl); 60 RawVAPtr = 0; 61 } 62} 63 64void StmtIteratorBase::NextDecl(bool ImmediateAdvance) { 65 assert (getVAPtr() == NULL); 66 67 if (inDecl()) { 68 assert(decl); 69 70 // FIXME: SIMPLIFY AWAY. 71 if (ImmediateAdvance) 72 decl = 0; 73 else if (HandleDecl(decl)) 74 return; 75 } 76 else { 77 assert(inDeclGroup()); 78 79 if (ImmediateAdvance) 80 ++DGI; 81 82 for ( ; DGI != DGE; ++DGI) 83 if (HandleDecl(*DGI)) 84 return; 85 } 86 87 RawVAPtr = 0; 88} 89 90bool StmtIteratorBase::HandleDecl(Decl* D) { 91 92 if (VarDecl* VD = dyn_cast<VarDecl>(D)) { 93 if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { 94 setVAPtr(VAPtr); 95 return true; 96 } 97 98 if (VD->getInit()) 99 return true; 100 } 101 else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) { 102 if (const VariableArrayType* VAPtr = 103 FindVA(TD->getUnderlyingType().getTypePtr())) { 104 setVAPtr(VAPtr); 105 return true; 106 } 107 } 108 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) { 109 if (ECD->getInitExpr()) 110 return true; 111 } 112 113 return false; 114} 115 116StmtIteratorBase::StmtIteratorBase(Decl *d, Stmt **s) 117 : stmt(s), decl(d), RawVAPtr(d ? DeclMode : 0) { 118 if (decl) 119 NextDecl(false); 120} 121 122StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) 123 : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { 124 NextDecl(false); 125} 126 127StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) 128 : stmt(0), decl(0), RawVAPtr(SizeOfTypeVAMode) { 129 RawVAPtr |= reinterpret_cast<uintptr_t>(t); 130} 131 132Stmt*& StmtIteratorBase::GetDeclExpr() const { 133 134 if (const VariableArrayType* VAPtr = getVAPtr()) { 135 assert (VAPtr->SizeExpr); 136 return const_cast<Stmt*&>(VAPtr->SizeExpr); 137 } 138 139 assert (inDecl() || inDeclGroup()); 140 141 if (inDeclGroup()) { 142 VarDecl* VD = cast<VarDecl>(*DGI); 143 return *VD->getInitAddress(); 144 } 145 146 assert (inDecl()); 147 148 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) { 149 assert (VD->Init); 150 return *VD->getInitAddress(); 151 } 152 153 EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl); 154 return ECD->Init; 155} 156