//===--- StmtIterator.cpp - Iterators for Statements ------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines internal methods for StmtIterator. // //===----------------------------------------------------------------------===// #include "clang/AST/StmtIterator.h" #include "clang/AST/Expr.h" #include "clang/AST/Decl.h" using namespace clang; static inline VariableArrayType* FindVA(Type* t) { while (ArrayType* vt = dyn_cast(t)) { if (VariableArrayType* vat = dyn_cast(vt)) if (vat->getSizeExpr()) return vat; t = vt->getElementType().getTypePtr(); } return NULL; } void StmtIteratorBase::NextVA() { assert (getVAPtr()); VariableArrayType* p = getVAPtr(); p = FindVA(p->getElementType().getTypePtr()); setVAPtr(p); if (!p && decl) { if (VarDecl* VD = dyn_cast(decl)) if (VD->Init) return; NextDecl(); } else { RawVAPtr = 0; } } void StmtIteratorBase::NextDecl(bool ImmediateAdvance) { assert (inDecl()); assert (getVAPtr() == NULL); assert (decl); if (ImmediateAdvance) { decl = decl->getNextDeclarator(); if (!decl) { RawVAPtr = 0; return; } } for ( ; decl ; decl = decl->getNextDeclarator()) { if (VarDecl* VD = dyn_cast(decl)) { if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { setVAPtr(VAPtr); return; } if (VD->getInit()) return; } else if (TypedefDecl* TD = dyn_cast(decl)) { if (VariableArrayType* VAPtr = FindVA(TD->getUnderlyingType().getTypePtr())) { setVAPtr(VAPtr); return; } } else if (EnumConstantDecl* ECD = dyn_cast(decl)) if (ECD->getInitExpr()) return; } if (!decl) { RawVAPtr = 0; return; } } StmtIteratorBase::StmtIteratorBase(ScopedDecl* d) : decl(d), RawVAPtr(DeclMode) { assert (decl); NextDecl(false); } StmtIteratorBase::StmtIteratorBase(VariableArrayType* t) : decl(NULL), RawVAPtr(SizeOfTypeVAMode) { RawVAPtr |= reinterpret_cast(t); } Stmt*& StmtIteratorBase::GetDeclExpr() const { if (VariableArrayType* VAPtr = getVAPtr()) { assert (VAPtr->SizeExpr); return reinterpret_cast(VAPtr->SizeExpr); } if (VarDecl* VD = dyn_cast(decl)) { assert (VD->Init); return reinterpret_cast(VD->Init); } EnumConstantDecl* ECD = cast(decl); return reinterpret_cast(ECD->Init); }