blob: 1ccba04d9f5bb133f38b94bb0fca3e0b1ff5db35 [file] [log] [blame]
Ted Kremenek336886a2007-10-18 00:24:38 +00001//===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-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 Kremenek336886a2007-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 Kremenek336886a2007-10-18 00:24:38 +000015#include "clang/AST/Decl.h"
16
17using namespace clang;
18
Douglas Gregor4619e432008-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 McCall424cec92011-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 Kremenek2f70e712007-10-29 20:50:16 +000024 if (vat->getSizeExpr())
25 return vat;
Mike Stump11289f42009-09-09 15:08:12 +000026
Ted Kremenek2f70e712007-10-29 20:50:16 +000027 t = vt->getElementType().getTypePtr();
Ted Kremenek2ba761c2007-10-18 18:19:31 +000028 }
Mike Stump11289f42009-09-09 15:08:12 +000029
Craig Topper36250ad2014-05-12 05:36:57 +000030 return nullptr;
Ted Kremenek2f70e712007-10-29 20:50:16 +000031}
32
33void StmtIteratorBase::NextVA() {
34 assert (getVAPtr());
35
John McCall424cec92011-01-19 06:33:43 +000036 const VariableArrayType *p = getVAPtr();
Ted Kremenek2f70e712007-10-29 20:50:16 +000037 p = FindVA(p->getElementType().getTypePtr());
38 setVAPtr(p);
39
Ted Kremenek587a44f2008-10-07 23:35:42 +000040 if (p)
41 return;
Mike Stump11289f42009-09-09 15:08:12 +000042
Eli Friedman2850ba82013-06-27 20:39:04 +000043 if (inDeclGroup()) {
Mike Stump11289f42009-09-09 15:08:12 +000044 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
Ted Kremenek587a44f2008-10-07 23:35:42 +000045 if (VD->Init)
46 return;
Mike Stump11289f42009-09-09 15:08:12 +000047
48 NextDecl();
Ted Kremenek587a44f2008-10-07 23:35:42 +000049 }
50 else {
Eli Friedman2850ba82013-06-27 20:39:04 +000051 assert(inSizeOfTypeVA());
Ted Kremenek85e45f22007-12-14 22:52:23 +000052 RawVAPtr = 0;
Eli Friedman0883bfb2008-05-21 05:06:46 +000053 }
Ted Kremenek2f70e712007-10-29 20:50:16 +000054}
55
56void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
Craig Topper36250ad2014-05-12 05:36:57 +000057 assert(getVAPtr() == nullptr);
Eli Friedman2850ba82013-06-27 20:39:04 +000058 assert(inDeclGroup());
Mike Stump11289f42009-09-09 15:08:12 +000059
Eli Friedman2850ba82013-06-27 20:39:04 +000060 if (ImmediateAdvance)
61 ++DGI;
Mike Stump11289f42009-09-09 15:08:12 +000062
Eli Friedman2850ba82013-06-27 20:39:04 +000063 for ( ; DGI != DGE; ++DGI)
64 if (HandleDecl(*DGI))
Chris Lattner5bbb3c82009-03-29 16:50:03 +000065 return;
Ted Kremenek2f70e712007-10-29 20:50:16 +000066
Ted Kremenekf9638ba2008-10-07 23:04:14 +000067 RawVAPtr = 0;
68}
69
70bool StmtIteratorBase::HandleDecl(Decl* D) {
Mike Stump11289f42009-09-09 15:08:12 +000071 if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
John McCall424cec92011-01-19 06:33:43 +000072 if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
Ted Kremenekf9638ba2008-10-07 23:04:14 +000073 setVAPtr(VAPtr);
74 return true;
Ted Kremenek2f70e712007-10-29 20:50:16 +000075 }
Mike Stump11289f42009-09-09 15:08:12 +000076
Ted Kremenekf9638ba2008-10-07 23:04:14 +000077 if (VD->getInit())
78 return true;
Ted Kremenek2f70e712007-10-29 20:50:16 +000079 }
Richard Smithdda56e42011-04-15 14:24:37 +000080 else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) {
John McCall424cec92011-01-19 06:33:43 +000081 if (const VariableArrayType* VAPtr =
Ted Kremenekf9638ba2008-10-07 23:04:14 +000082 FindVA(TD->getUnderlyingType().getTypePtr())) {
83 setVAPtr(VAPtr);
84 return true;
85 }
Ted Kremenek899ef132007-10-29 21:23:58 +000086 }
Ted Kremenekf9638ba2008-10-07 23:04:14 +000087 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
88 if (ECD->getInitExpr())
89 return true;
90 }
91
Mike Stump11289f42009-09-09 15:08:12 +000092 return false;
Ted Kremenek2f70e712007-10-29 20:50:16 +000093}
94
Ted Kremenekf9638ba2008-10-07 23:04:14 +000095StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
Craig Topper36250ad2014-05-12 05:36:57 +000096 : stmt(nullptr), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
Ted Kremenekf9638ba2008-10-07 23:04:14 +000097 NextDecl(false);
98}
99
John McCall424cec92011-01-19 06:33:43 +0000100StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
Craig Topper36250ad2014-05-12 05:36:57 +0000101 : stmt(nullptr), DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
Ted Kremenek85e45f22007-12-14 22:52:23 +0000102 RawVAPtr |= reinterpret_cast<uintptr_t>(t);
103}
104
Ted Kremenek066f6032007-10-25 22:24:19 +0000105Stmt*& StmtIteratorBase::GetDeclExpr() const {
John McCall424cec92011-01-19 06:33:43 +0000106 if (const VariableArrayType* VAPtr = getVAPtr()) {
Ted Kremenek2f70e712007-10-29 20:50:16 +0000107 assert (VAPtr->SizeExpr);
John McCall424cec92011-01-19 06:33:43 +0000108 return const_cast<Stmt*&>(VAPtr->SizeExpr);
Ted Kremenek066f6032007-10-25 22:24:19 +0000109 }
Ted Kremenekbe485b62009-03-11 18:17:16 +0000110
Eli Friedman2850ba82013-06-27 20:39:04 +0000111 assert (inDeclGroup());
112 VarDecl* VD = cast<VarDecl>(*DGI);
113 return *VD->getInitAddress();
Ted Kremenek336886a2007-10-18 00:24:38 +0000114}