blob: 9bf4aeaae83e9c9d245fc649a75df7c7a6f8a2bc [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?
John McCallf4c73712011-01-19 06:33:43 +000021static inline const VariableArrayType *FindVA(const Type* t) {
22 while (const ArrayType *vt = dyn_cast<ArrayType>(t)) {
23 if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt))
Ted Kremenek92866e22007-10-29 20:50:16 +000024 if (vat->getSizeExpr())
25 return vat;
Mike Stump1eb44332009-09-09 15:08:12 +000026
Ted Kremenek92866e22007-10-29 20:50:16 +000027 t = vt->getElementType().getTypePtr();
Ted Kremenekc325e7f2007-10-18 18:19:31 +000028 }
Mike Stump1eb44332009-09-09 15:08:12 +000029
Ted Kremenek92866e22007-10-29 20:50:16 +000030 return NULL;
31}
32
33void StmtIteratorBase::NextVA() {
34 assert (getVAPtr());
35
John McCallf4c73712011-01-19 06:33:43 +000036 const VariableArrayType *p = getVAPtr();
Ted Kremenek92866e22007-10-29 20:50:16 +000037 p = FindVA(p->getElementType().getTypePtr());
38 setVAPtr(p);
39
Ted Kremenek8a213de2008-10-07 23:35:42 +000040 if (p)
41 return;
Mike Stump1eb44332009-09-09 15:08:12 +000042
Ted Kremenek8a213de2008-10-07 23:35:42 +000043 if (inDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +000044 if (VarDecl* VD = dyn_cast<VarDecl>(decl))
Ted Kremenek8a213de2008-10-07 23:35:42 +000045 if (VD->Init)
46 return;
Mike Stump1eb44332009-09-09 15:08:12 +000047
Ted Kremenek8a213de2008-10-07 23:35:42 +000048 NextDecl();
49 }
50 else if (inDeclGroup()) {
Mike Stump1eb44332009-09-09 15:08:12 +000051 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
Ted Kremenek8a213de2008-10-07 23:35:42 +000052 if (VD->Init)
53 return;
Mike Stump1eb44332009-09-09 15:08:12 +000054
55 NextDecl();
Ted Kremenek8a213de2008-10-07 23:35:42 +000056 }
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);
Mike Stump1eb44332009-09-09 15:08:12 +000066
Ted Kremenek3e6d1202008-10-07 23:04:14 +000067 if (inDecl()) {
Ted Kremenek35628d12009-12-23 23:38:34 +000068 assert(decl);
Mike Stump1eb44332009-09-09 15:08:12 +000069
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 {
Ted Kremenek35628d12009-12-23 23:38:34 +000077 assert(inDeclGroup());
Mike Stump1eb44332009-09-09 15:08:12 +000078
Ted Kremenek3e6d1202008-10-07 23:04:14 +000079 if (ImmediateAdvance)
80 ++DGI;
Mike Stump1eb44332009-09-09 15:08:12 +000081
Ted Kremenek3e6d1202008-10-07 23:04:14 +000082 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) {
Mike Stump1eb44332009-09-09 15:08:12 +000091
92 if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
John McCallf4c73712011-01-19 06:33:43 +000093 if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
Ted Kremenek3e6d1202008-10-07 23:04:14 +000094 setVAPtr(VAPtr);
95 return true;
Ted Kremenek92866e22007-10-29 20:50:16 +000096 }
Mike Stump1eb44332009-09-09 15:08:12 +000097
Ted Kremenek3e6d1202008-10-07 23:04:14 +000098 if (VD->getInit())
99 return true;
Ted Kremenek92866e22007-10-29 20:50:16 +0000100 }
Richard Smith162e1c12011-04-15 14:24:37 +0000101 else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) {
John McCallf4c73712011-01-19 06:33:43 +0000102 if (const VariableArrayType* VAPtr =
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000103 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
Mike Stump1eb44332009-09-09 15:08:12 +0000113 return false;
Ted Kremenek92866e22007-10-29 20:50:16 +0000114}
115
Ted Kremenek35628d12009-12-23 23:38:34 +0000116StmtIteratorBase::StmtIteratorBase(Decl *d, Stmt **s)
117 : stmt(s), decl(d), RawVAPtr(d ? DeclMode : 0) {
118 if (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)
Ted Kremenekb03f6302009-12-23 22:31:49 +0000123 : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000124 NextDecl(false);
125}
126
John McCallf4c73712011-01-19 06:33:43 +0000127StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
Ted Kremenekb03f6302009-12-23 22:31:49 +0000128 : stmt(0), 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 {
Mike Stump1eb44332009-09-09 15:08:12 +0000133
John McCallf4c73712011-01-19 06:33:43 +0000134 if (const VariableArrayType* VAPtr = getVAPtr()) {
Ted Kremenek92866e22007-10-29 20:50:16 +0000135 assert (VAPtr->SizeExpr);
John McCallf4c73712011-01-19 06:33:43 +0000136 return const_cast<Stmt*&>(VAPtr->SizeExpr);
Ted Kremenekb990f182007-10-25 22:24:19 +0000137 }
Ted Kremenek344d4c82009-03-11 18:17:16 +0000138
139 assert (inDecl() || inDeclGroup());
Mike Stump1eb44332009-09-09 15:08:12 +0000140
Ted Kremenek344d4c82009-03-11 18:17:16 +0000141 if (inDeclGroup()) {
142 VarDecl* VD = cast<VarDecl>(*DGI);
Douglas Gregor78d15832009-05-26 18:54:04 +0000143 return *VD->getInitAddress();
Ted Kremenek344d4c82009-03-11 18:17:16 +0000144 }
Mike Stump1eb44332009-09-09 15:08:12 +0000145
Ted Kremenek3e6d1202008-10-07 23:04:14 +0000146 assert (inDecl());
Ted Kremenek92866e22007-10-29 20:50:16 +0000147
148 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
149 assert (VD->Init);
Douglas Gregor78d15832009-05-26 18:54:04 +0000150 return *VD->getInitAddress();
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}