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 #include "clang/AST/Type.h" 17 #include "clang/Basic/LLVM.h" 18 #include "llvm/Support/Casting.h" 19 #include <cassert> 20 #include <cstdint> 21 22 using namespace clang; 23 24 // FIXME: Add support for dependent-sized array types in C++? 25 // Does it even make sense to build a CFG for an uninstantiated template? 26 static inline const VariableArrayType *FindVA(const Type* t) { 27 while (const ArrayType *vt = dyn_cast<ArrayType>(t)) { 28 if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt)) 29 if (vat->getSizeExpr()) 30 return vat; 31 32 t = vt->getElementType().getTypePtr(); 33 } 34 35 return nullptr; 36 } 37 38 void StmtIteratorBase::NextVA() { 39 assert(getVAPtr()); 40 41 const VariableArrayType *p = getVAPtr(); 42 p = FindVA(p->getElementType().getTypePtr()); 43 setVAPtr(p); 44 45 if (p) 46 return; 47 48 if (inDeclGroup()) { 49 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI)) 50 if (VD->hasInit()) 51 return; 52 53 NextDecl(); 54 } 55 else { 56 assert(inSizeOfTypeVA()); 57 RawVAPtr = 0; 58 } 59 } 60 61 void StmtIteratorBase::NextDecl(bool ImmediateAdvance) { 62 assert(getVAPtr() == nullptr); 63 assert(inDeclGroup()); 64 65 if (ImmediateAdvance) 66 ++DGI; 67 68 for ( ; DGI != DGE; ++DGI) 69 if (HandleDecl(*DGI)) 70 return; 71 72 RawVAPtr = 0; 73 } 74 75 bool StmtIteratorBase::HandleDecl(Decl* D) { 76 if (VarDecl* VD = dyn_cast<VarDecl>(D)) { 77 if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { 78 setVAPtr(VAPtr); 79 return true; 80 } 81 82 if (VD->getInit()) 83 return true; 84 } 85 else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) { 86 if (const VariableArrayType* VAPtr = 87 FindVA(TD->getUnderlyingType().getTypePtr())) { 88 setVAPtr(VAPtr); 89 return true; 90 } 91 } 92 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) { 93 if (ECD->getInitExpr()) 94 return true; 95 } 96 97 return false; 98 } 99 100 StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) 101 : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { 102 NextDecl(false); 103 } 104 105 StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) 106 : DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) { 107 RawVAPtr |= reinterpret_cast<uintptr_t>(t); 108 } 109 110 Stmt*& StmtIteratorBase::GetDeclExpr() const { 111 if (const VariableArrayType* VAPtr = getVAPtr()) { 112 assert(VAPtr->SizeExpr); 113 return const_cast<Stmt*&>(VAPtr->SizeExpr); 114 } 115 116 assert(inDeclGroup()); 117 VarDecl* VD = cast<VarDecl>(*DGI); 118 return *VD->getInitAddress(); 119 } 120