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