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