clang API Documentation

StmtIterator.cpp
Go to the documentation of this file.
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 }