• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
2  //
3  //                     The LLVM Compiler Infrastructure
4  //
5  // This file is distributed under the University of Illinois Open Source
6  // 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"
15  #include "clang/AST/Decl.h"
16  
17  using namespace clang;
18  
19  // FIXME: Add support for dependent-sized array types in C++?
20  // Does it even make sense to build a CFG for an uninstantiated template?
FindVA(const Type * t)21  static 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))
24        if (vat->getSizeExpr())
25          return vat;
26  
27      t = vt->getElementType().getTypePtr();
28    }
29  
30    return NULL;
31  }
32  
NextVA()33  void StmtIteratorBase::NextVA() {
34    assert (getVAPtr());
35  
36    const VariableArrayType *p = getVAPtr();
37    p = FindVA(p->getElementType().getTypePtr());
38    setVAPtr(p);
39  
40    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());
59      assert(!decl);
60      RawVAPtr = 0;
61    }
62  }
63  
NextDecl(bool ImmediateAdvance)64  void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
65    assert (getVAPtr() == NULL);
66  
67    if (inDecl()) {
68      assert(decl);
69  
70      // FIXME: SIMPLIFY AWAY.
71      if (ImmediateAdvance)
72        decl = 0;
73      else if (HandleDecl(decl))
74        return;
75    }
76    else {
77      assert(inDeclGroup());
78  
79      if (ImmediateAdvance)
80        ++DGI;
81  
82      for ( ; DGI != DGE; ++DGI)
83        if (HandleDecl(*DGI))
84          return;
85    }
86  
87    RawVAPtr = 0;
88  }
89  
HandleDecl(Decl * D)90  bool StmtIteratorBase::HandleDecl(Decl* D) {
91  
92    if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
93      if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
94        setVAPtr(VAPtr);
95        return true;
96      }
97  
98      if (VD->getInit())
99        return true;
100    }
101    else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) {
102      if (const VariableArrayType* VAPtr =
103          FindVA(TD->getUnderlyingType().getTypePtr())) {
104        setVAPtr(VAPtr);
105        return true;
106      }
107    }
108    else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
109      if (ECD->getInitExpr())
110        return true;
111    }
112  
113    return false;
114  }
115  
StmtIteratorBase(Decl * d,Stmt ** s)116  StmtIteratorBase::StmtIteratorBase(Decl *d, Stmt **s)
117    : stmt(s), decl(d), RawVAPtr(d ? DeclMode : 0) {
118    if (decl)
119      NextDecl(false);
120  }
121  
StmtIteratorBase(Decl ** dgi,Decl ** dge)122  StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
123    : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
124    NextDecl(false);
125  }
126  
StmtIteratorBase(const VariableArrayType * t)127  StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
128    : stmt(0), decl(0), RawVAPtr(SizeOfTypeVAMode) {
129    RawVAPtr |= reinterpret_cast<uintptr_t>(t);
130  }
131  
GetDeclExpr() const132  Stmt*& StmtIteratorBase::GetDeclExpr() const {
133  
134    if (const VariableArrayType* VAPtr = getVAPtr()) {
135      assert (VAPtr->SizeExpr);
136      return const_cast<Stmt*&>(VAPtr->SizeExpr);
137    }
138  
139    assert (inDecl() || inDeclGroup());
140  
141    if (inDeclGroup()) {
142      VarDecl* VD = cast<VarDecl>(*DGI);
143      return *VD->getInitAddress();
144    }
145  
146    assert (inDecl());
147  
148    if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
149      assert (VD->Init);
150      return *VD->getInitAddress();
151    }
152  
153    EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
154    return ECD->Init;
155  }
156