blob: 20024f513ffcea6228c745231b8d71149ae9db8f [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
Chris Lattner682bf922009-03-29 16:50:03 +000070 // FIXME: SIMPLIFY AWAY.
Ted Kremenek3e6d1202008-10-07 23:04:14 +000071 if (ImmediateAdvance)
Chris Lattner682bf922009-03-29 16:50:03 +000072 decl = 0;
73 else if (HandleDecl(decl))
74 return;
Ted Kremenek3e6d1202008-10-07 23:04:14 +000075 }
76 else {
77 assert (inDeclGroup());
78
79 if (ImmediateAdvance)
80 ++DGI;
81
82 for ( ; DGI != DGE; ++DGI)
83 if (HandleDecl(*DGI))
84 return;
85 }
Ted Kremenek92866e22007-10-29 20:50:16 +000086
Ted Kremenek3e6d1202008-10-07 23:04:14 +000087 RawVAPtr = 0;
88}
89
90bool StmtIteratorBase::HandleDecl(Decl* D) {
91
92 if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
93 if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
94 setVAPtr(VAPtr);
95 return true;
Ted Kremenek92866e22007-10-29 20:50:16 +000096 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +000097
98 if (VD->getInit())
99 return true;
Ted Kremenek92866e22007-10-29 20:50:16 +0000100 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000101 else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(D)) {
102 if (VariableArrayType* VAPtr =
103 FindVA(TD->getUnderlyingType().getTypePtr())) {
104 setVAPtr(VAPtr);
105 return true;
106 }
Ted Kremenek103a1b42007-10-29 21:23:58 +0000107 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000108 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
109 if (ECD->getInitExpr())
110 return true;
111 }
112
113 return false;
Ted Kremenek92866e22007-10-29 20:50:16 +0000114}
115
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000116StmtIteratorBase::StmtIteratorBase(Decl* d)
Ted Kremenek92866e22007-10-29 20:50:16 +0000117 : decl(d), RawVAPtr(DeclMode) {
118 assert (decl);
119 NextDecl(false);
Ted Kremenekc7c326a2007-10-18 16:25:40 +0000120}
Ted Kremenek9caf8b12007-10-18 00:24:38 +0000121
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000122StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
123 : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
124 NextDecl(false);
125}
126
Ted Kremenek699e9fb2007-12-14 22:52:23 +0000127StmtIteratorBase::StmtIteratorBase(VariableArrayType* t)
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000128: decl(0), RawVAPtr(SizeOfTypeVAMode) {
Ted Kremenek699e9fb2007-12-14 22:52:23 +0000129 RawVAPtr |= reinterpret_cast<uintptr_t>(t);
130}
131
Ted Kremenekb990f182007-10-25 22:24:19 +0000132Stmt*& StmtIteratorBase::GetDeclExpr() const {
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000133
Ted Kremenek92866e22007-10-29 20:50:16 +0000134 if (VariableArrayType* VAPtr = getVAPtr()) {
135 assert (VAPtr->SizeExpr);
Ted Kremenekb3064042008-05-30 16:14:41 +0000136 return VAPtr->SizeExpr;
Ted Kremenekb990f182007-10-25 22:24:19 +0000137 }
Ted Kremenek344d4c82009-03-11 18:17:16 +0000138
139 assert (inDecl() || inDeclGroup());
140
141 if (inDeclGroup()) {
142 VarDecl* VD = cast<VarDecl>(*DGI);
143 return VD->Init;
144 }
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000145
146 assert (inDecl());
Ted Kremenek92866e22007-10-29 20:50:16 +0000147
148 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
149 assert (VD->Init);
Ted Kremenekb3064042008-05-30 16:14:41 +0000150 return VD->Init;
Ted Kremenek92866e22007-10-29 20:50:16 +0000151 }
152
153 EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
Ted Kremenekb3064042008-05-30 16:14:41 +0000154 return ECD->Init;
Ted Kremenek9caf8b12007-10-18 00:24:38 +0000155}