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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/lib/AST/StmtIterator.cpp