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