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