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 nullptr; 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 (inDeclGroup()) { 00044 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI)) 00045 if (VD->Init) 00046 return; 00047 00048 NextDecl(); 00049 } 00050 else { 00051 assert(inSizeOfTypeVA()); 00052 RawVAPtr = 0; 00053 } 00054 } 00055 00056 void StmtIteratorBase::NextDecl(bool ImmediateAdvance) { 00057 assert(getVAPtr() == nullptr); 00058 assert(inDeclGroup()); 00059 00060 if (ImmediateAdvance) 00061 ++DGI; 00062 00063 for ( ; DGI != DGE; ++DGI) 00064 if (HandleDecl(*DGI)) 00065 return; 00066 00067 RawVAPtr = 0; 00068 } 00069 00070 bool StmtIteratorBase::HandleDecl(Decl* D) { 00071 if (VarDecl* VD = dyn_cast<VarDecl>(D)) { 00072 if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { 00073 setVAPtr(VAPtr); 00074 return true; 00075 } 00076 00077 if (VD->getInit()) 00078 return true; 00079 } 00080 else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) { 00081 if (const VariableArrayType* VAPtr = 00082 FindVA(TD->getUnderlyingType().getTypePtr())) { 00083 setVAPtr(VAPtr); 00084 return true; 00085 } 00086 } 00087 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) { 00088 if (ECD->getInitExpr()) 00089 return true; 00090 } 00091 00092 return false; 00093 } 00094 00095 StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) 00096 : stmt(nullptr), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { 00097 NextDecl(false); 00098 } 00099 00100 StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) 00101 : stmt(nullptr), DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) { 00102 RawVAPtr |= reinterpret_cast<uintptr_t>(t); 00103 } 00104 00105 Stmt*& StmtIteratorBase::GetDeclExpr() const { 00106 if (const VariableArrayType* VAPtr = getVAPtr()) { 00107 assert (VAPtr->SizeExpr); 00108 return const_cast<Stmt*&>(VAPtr->SizeExpr); 00109 } 00110 00111 assert (inDeclGroup()); 00112 VarDecl* VD = cast<VarDecl>(*DGI); 00113 return *VD->getInitAddress(); 00114 }