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 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 }