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