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