blob: ae6de11e11fe6a308e238ca140561046a3ce3ade [file] [log] [blame]
Ted Kremenek9caf8b12007-10-18 00:24:38 +00001//===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Ted Kremenek and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines internal methods for StmtIterator.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/StmtIterator.h"
Ted Kremenekc325e7f2007-10-18 18:19:31 +000015#include "clang/AST/Expr.h"
Ted Kremenek9caf8b12007-10-18 00:24:38 +000016#include "clang/AST/Decl.h"
17
18using namespace clang;
19
Ted Kremenek92866e22007-10-29 20:50:16 +000020static inline VariableArrayType* FindVA(Type* t) {
21 while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
22 if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
23 if (vat->getSizeExpr())
24 return vat;
25
26 t = vt->getElementType().getTypePtr();
Ted Kremenekc325e7f2007-10-18 18:19:31 +000027 }
28
Ted Kremenek92866e22007-10-29 20:50:16 +000029 return NULL;
30}
31
32void StmtIteratorBase::NextVA() {
33 assert (getVAPtr());
Ted Kremenek103a1b42007-10-29 21:23:58 +000034 assert (decl);
Ted Kremenek92866e22007-10-29 20:50:16 +000035
36 VariableArrayType* p = getVAPtr();
37 p = FindVA(p->getElementType().getTypePtr());
38 setVAPtr(p);
39
40 if (!p) {
Ted Kremenek771fe162007-10-29 21:38:03 +000041 if (VarDecl* VD = dyn_cast<VarDecl>(decl))
42 if (VD->Init)
43 return;
44
45 NextDecl();
Ted Kremenek92866e22007-10-29 20:50:16 +000046 }
47}
48
49void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
50 assert (inDeclMode());
51 assert (getVAPtr() == NULL);
52 assert (decl);
53
54 if (ImmediateAdvance) {
55 decl = decl->getNextDeclarator();
56
57 if (!decl) {
58 RawVAPtr = 0;
59 return;
60 }
61 }
62
63 for ( ; decl ; decl = decl->getNextDeclarator()) {
Ted Kremenek92866e22007-10-29 20:50:16 +000064 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
65 if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
66 setVAPtr(VAPtr);
67 return;
68 }
69
70 if (VD->getInit())
71 return;
72 }
Ted Kremenek771fe162007-10-29 21:38:03 +000073 else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(decl)) {
74 if (VariableArrayType* VAPtr =
75 FindVA(TD->getUnderlyingType().getTypePtr())) {
76 setVAPtr(VAPtr);
77 return;
78 }
79 }
Ted Kremenek92866e22007-10-29 20:50:16 +000080 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(decl))
81 if (ECD->getInitExpr())
82 return;
83 }
Ted Kremenek103a1b42007-10-29 21:23:58 +000084
85 if (!decl) {
86 RawVAPtr = 0;
87 return;
88 }
Ted Kremenek92866e22007-10-29 20:50:16 +000089}
90
91StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
92 : decl(d), RawVAPtr(DeclMode) {
93 assert (decl);
94 NextDecl(false);
Ted Kremenekc7c326a2007-10-18 16:25:40 +000095}
Ted Kremenek9caf8b12007-10-18 00:24:38 +000096
Ted Kremenekb990f182007-10-25 22:24:19 +000097Stmt*& StmtIteratorBase::GetDeclExpr() const {
Ted Kremenek92866e22007-10-29 20:50:16 +000098 if (VariableArrayType* VAPtr = getVAPtr()) {
99 assert (VAPtr->SizeExpr);
100 return reinterpret_cast<Stmt*&>(VAPtr->SizeExpr);
Ted Kremenekb990f182007-10-25 22:24:19 +0000101 }
Ted Kremenek92866e22007-10-29 20:50:16 +0000102
103 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
104 assert (VD->Init);
105 return reinterpret_cast<Stmt*&>(VD->Init);
106 }
107
108 EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
109 return reinterpret_cast<Stmt*&>(ECD->Init);
Ted Kremenek9caf8b12007-10-18 00:24:38 +0000110}