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