clang API Documentation
00001 //===--- StmtIterator.cpp - Iterators for Statements ------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines internal methods for StmtIterator. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/AST/StmtIterator.h" 00015 #include "clang/AST/Decl.h" 00016 00017 using namespace clang; 00018 00019 // FIXME: Add support for dependent-sized array types in C++? 00020 // Does it even make sense to build a CFG for an uninstantiated template? 00021 static inline const VariableArrayType *FindVA(const Type* t) { 00022 while (const ArrayType *vt = dyn_cast<ArrayType>(t)) { 00023 if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt)) 00024 if (vat->getSizeExpr()) 00025 return vat; 00026 00027 t = vt->getElementType().getTypePtr(); 00028 } 00029 00030 return NULL; 00031 } 00032 00033 void StmtIteratorBase::NextVA() { 00034 assert (getVAPtr()); 00035 00036 const VariableArrayType *p = getVAPtr(); 00037 p = FindVA(p->getElementType().getTypePtr()); 00038 setVAPtr(p); 00039 00040 if (p) 00041 return; 00042 00043 if (inDecl()) { 00044 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) 00045 if (VD->Init) 00046 return; 00047 00048 NextDecl(); 00049 } 00050 else if (inDeclGroup()) { 00051 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI)) 00052 if (VD->Init) 00053 return; 00054 00055 NextDecl(); 00056 } 00057 else { 00058 assert (inSizeOfTypeVA()); 00059 assert(!decl); 00060 RawVAPtr = 0; 00061 } 00062 } 00063 00064 void StmtIteratorBase::NextDecl(bool ImmediateAdvance) { 00065 assert (getVAPtr() == NULL); 00066 00067 if (inDecl()) { 00068 assert(decl); 00069 00070 // FIXME: SIMPLIFY AWAY. 00071 if (ImmediateAdvance) 00072 decl = 0; 00073 else if (HandleDecl(decl)) 00074 return; 00075 } 00076 else { 00077 assert(inDeclGroup()); 00078 00079 if (ImmediateAdvance) 00080 ++DGI; 00081 00082 for ( ; DGI != DGE; ++DGI) 00083 if (HandleDecl(*DGI)) 00084 return; 00085 } 00086 00087 RawVAPtr = 0; 00088 } 00089 00090 bool StmtIteratorBase::HandleDecl(Decl* D) { 00091 00092 if (VarDecl* VD = dyn_cast<VarDecl>(D)) { 00093 if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { 00094 setVAPtr(VAPtr); 00095 return true; 00096 } 00097 00098 if (VD->getInit()) 00099 return true; 00100 } 00101 else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) { 00102 if (const VariableArrayType* VAPtr = 00103 FindVA(TD->getUnderlyingType().getTypePtr())) { 00104 setVAPtr(VAPtr); 00105 return true; 00106 } 00107 } 00108 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) { 00109 if (ECD->getInitExpr()) 00110 return true; 00111 } 00112 00113 return false; 00114 } 00115 00116 StmtIteratorBase::StmtIteratorBase(Decl *d, Stmt **s) 00117 : stmt(s), decl(d), RawVAPtr(d ? DeclMode : 0) { 00118 if (decl) 00119 NextDecl(false); 00120 } 00121 00122 StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) 00123 : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { 00124 NextDecl(false); 00125 } 00126 00127 StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) 00128 : stmt(0), decl(0), RawVAPtr(SizeOfTypeVAMode) { 00129 RawVAPtr |= reinterpret_cast<uintptr_t>(t); 00130 } 00131 00132 Stmt*& StmtIteratorBase::GetDeclExpr() const { 00133 00134 if (const VariableArrayType* VAPtr = getVAPtr()) { 00135 assert (VAPtr->SizeExpr); 00136 return const_cast<Stmt*&>(VAPtr->SizeExpr); 00137 } 00138 00139 assert (inDecl() || inDeclGroup()); 00140 00141 if (inDeclGroup()) { 00142 VarDecl* VD = cast<VarDecl>(*DGI); 00143 return *VD->getInitAddress(); 00144 } 00145 00146 assert (inDecl()); 00147 00148 if (VarDecl* VD = dyn_cast<VarDecl>(decl)) { 00149 assert (VD->Init); 00150 return *VD->getInitAddress(); 00151 } 00152 00153 EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl); 00154 return ECD->Init; 00155 }