blob: 48003450191827d3a620c112a9e0e49d2108c764 [file] [log] [blame]
Ted Kremenek9caf8b12007-10-18 00:24:38 +00001//===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Ted Kremenek9caf8b12007-10-18 00:24:38 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file defines internal methods for StmtIterator.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/StmtIterator.h"
Ted Kremenek9caf8b12007-10-18 00:24:38 +000015#include "clang/AST/Decl.h"
16
17using namespace clang;
18
Douglas Gregor898574e2008-12-05 23:32:09 +000019// FIXME: Add support for dependent-sized array types in C++?
20// Does it even make sense to build a CFG for an uninstantiated template?
Ted Kremenek92866e22007-10-29 20:50:16 +000021static inline VariableArrayType* FindVA(Type* t) {
22 while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
23 if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
24 if (vat->getSizeExpr())
25 return vat;
26
27 t = vt->getElementType().getTypePtr();
Ted Kremenekc325e7f2007-10-18 18:19:31 +000028 }
29
Ted Kremenek92866e22007-10-29 20:50:16 +000030 return NULL;
31}
32
33void StmtIteratorBase::NextVA() {
34 assert (getVAPtr());
35
36 VariableArrayType* p = getVAPtr();
37 p = FindVA(p->getElementType().getTypePtr());
38 setVAPtr(p);
39
Ted Kremenek8a213de2008-10-07 23:35:42 +000040 if (p)
41 return;
42
43 if (inDecl()) {
44 if (VarDecl* VD = dyn_cast<VarDecl>(decl))
45 if (VD->Init)
46 return;
47
48 NextDecl();
49 }
50 else if (inDeclGroup()) {
51 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
52 if (VD->Init)
53 return;
54
55 NextDecl();
56 }
57 else {
58 assert (inSizeOfTypeVA());
Eli Friedmanb0c05542008-05-21 05:06:46 +000059 assert(!decl);
Ted Kremenek699e9fb2007-12-14 22:52:23 +000060 RawVAPtr = 0;
Eli Friedmanb0c05542008-05-21 05:06:46 +000061 }
Ted Kremenek92866e22007-10-29 20:50:16 +000062}
63
64void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
Ted Kremenek92866e22007-10-29 20:50:16 +000065 assert (getVAPtr() == NULL);
Ted Kremenek92866e22007-10-29 20:50:16 +000066
Ted Kremenek3e6d1202008-10-07 23:04:14 +000067 if (inDecl()) {
68 assert (decl);
69
70 if (ImmediateAdvance)
71 decl = decl->getNextDeclarator();
72
73 for ( ; decl ; decl = decl->getNextDeclarator())
74 if (HandleDecl(decl))
75 return;
76 }
77 else {
78 assert (inDeclGroup());
79
80 if (ImmediateAdvance)
81 ++DGI;
82
83 for ( ; DGI != DGE; ++DGI)
84 if (HandleDecl(*DGI))
85 return;
86 }
Ted Kremenek92866e22007-10-29 20:50:16 +000087
Ted Kremenek3e6d1202008-10-07 23:04:14 +000088 RawVAPtr = 0;
89}
90
91bool StmtIteratorBase::HandleDecl(Decl* D) {
92
93 if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
94 if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
95 setVAPtr(VAPtr);
96 return true;
Ted Kremenek92866e22007-10-29 20:50:16 +000097 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +000098
99 if (VD->getInit())
100 return true;
Ted Kremenek92866e22007-10-29 20:50:16 +0000101 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000102 else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(D)) {
103 if (VariableArrayType* VAPtr =
104 FindVA(TD->getUnderlyingType().getTypePtr())) {
105 setVAPtr(VAPtr);
106 return true;
107 }
Ted Kremenek103a1b42007-10-29 21:23:58 +0000108 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000109 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
110 if (ECD->getInitExpr())
111 return true;
112 }
113
114 return false;
Ted Kremenek92866e22007-10-29 20:50:16 +0000115}
116
117StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
118 : decl(d), RawVAPtr(DeclMode) {
119 assert (decl);
120 NextDecl(false);
Ted Kremenekc7c326a2007-10-18 16:25:40 +0000121}
Ted Kremenek9caf8b12007-10-18 00:24:38 +0000122
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000123StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
124 : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
125 NextDecl(false);
126}
127
Ted Kremenek699e9fb2007-12-14 22:52:23 +0000128StmtIteratorBase::StmtIteratorBase(VariableArrayType* t)
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000129: decl(0), RawVAPtr(SizeOfTypeVAMode) {
Ted Kremenek699e9fb2007-12-14 22:52:23 +0000130 RawVAPtr |= reinterpret_cast<uintptr_t>(t);
131}
132
Ted Kremenekb990f182007-10-25 22:24:19 +0000133Stmt*& StmtIteratorBase::GetDeclExpr() const {
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000134
135 if (inDeclGroup()) {
136 VarDecl* VD = cast<VarDecl>(*DGI);
137 return VD->Init;
138 }
139
140 assert (inDecl() || inSizeOfTypeVA());
141
Ted Kremenek92866e22007-10-29 20:50:16 +0000142 if (VariableArrayType* VAPtr = getVAPtr()) {
143 assert (VAPtr->SizeExpr);
Ted Kremenekb3064042008-05-30 16:14:41 +0000144 return VAPtr->SizeExpr;
Ted Kremenekb990f182007-10-25 22:24:19 +0000145 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000146
147 assert (inDecl());
Ted Kremenek92866e22007-10-29 20:50:16 +0000148
149 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
150 assert (VD->Init);
Ted Kremenekb3064042008-05-30 16:14:41 +0000151 return VD->Init;
Ted Kremenek92866e22007-10-29 20:50:16 +0000152 }
153
154 EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
Ted Kremenekb3064042008-05-30 16:14:41 +0000155 return ECD->Init;
Ted Kremenek9caf8b12007-10-18 00:24:38 +0000156}