19caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//===--- StmtIterator.cpp - Iterators for Statements ------------------------===// 29caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// 39caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// The LLVM Compiler Infrastructure 49caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 79caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// 89caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//===----------------------------------------------------------------------===// 99caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// 109caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// This file defines internal methods for StmtIterator. 119caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// 129caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//===----------------------------------------------------------------------===// 139caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek 149caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek#include "clang/AST/StmtIterator.h" 159caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek#include "clang/AST/Decl.h" 169caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek 179caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenekusing namespace clang; 189caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek 19898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// FIXME: Add support for dependent-sized array types in C++? 20898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// Does it even make sense to build a CFG for an uninstantiated template? 21f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCallstatic inline const VariableArrayType *FindVA(const Type* t) { 22f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall while (const ArrayType *vt = dyn_cast<ArrayType>(t)) { 23f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt)) 2492866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek if (vat->getSizeExpr()) 2592866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek return vat; 261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2792866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek t = vt->getElementType().getTypePtr(); 2892866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek } 291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3092866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek return NULL; 31b990f1834b4ba1c8e67ace010b0f554d0e59c1eaTed Kremenek} 32b990f1834b4ba1c8e67ace010b0f554d0e59c1eaTed Kremenek 3392866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenekvoid StmtIteratorBase::NextVA() { 3492866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek assert (getVAPtr()); 35c7c326ad0c407dbd2a406de0f961283a790f8725Ted Kremenek 36f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall const VariableArrayType *p = getVAPtr(); 3792866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek p = FindVA(p->getElementType().getTypePtr()); 3892866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek setVAPtr(p); 39c7c326ad0c407dbd2a406de0f961283a790f8725Ted Kremenek 408a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek if (p) 418a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek return; 421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 438a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek if (inDecl()) { 441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (VarDecl* VD = dyn_cast<VarDecl>(decl)) 458a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek if (VD->Init) 468a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek return; 471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 488a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek NextDecl(); 498a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek } 508a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek else if (inDeclGroup()) { 511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (VarDecl* VD = dyn_cast<VarDecl>(*DGI)) 528a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek if (VD->Init) 538a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek return; 541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump NextDecl(); 568a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek } 578a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek else { 588a213de1a86e5f347c6b591f52712c2fd6177cceTed Kremenek assert (inSizeOfTypeVA()); 59b0c0554bd62689f48a1c42fc46c78c531cdb3cbfEli Friedman assert(!decl); 60699e9fbeae34cdd651b8e6308649c8939f090cbdTed Kremenek RawVAPtr = 0; 61b0c0554bd62689f48a1c42fc46c78c531cdb3cbfEli Friedman } 62c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek} 63c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek 6492866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenekvoid StmtIteratorBase::NextDecl(bool ImmediateAdvance) { 6592866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek assert (getVAPtr() == NULL); 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 673e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek if (inDecl()) { 6835628d1f17c817f8c240208db7ba490e3109981bTed Kremenek assert(decl); 691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 70682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // FIXME: SIMPLIFY AWAY. 713e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek if (ImmediateAdvance) 72682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner decl = 0; 73682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner else if (HandleDecl(decl)) 74682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 753e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek } 763e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek else { 7735628d1f17c817f8c240208db7ba490e3109981bTed Kremenek assert(inDeclGroup()); 781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 793e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek if (ImmediateAdvance) 803e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek ++DGI; 811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 823e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek for ( ; DGI != DGE; ++DGI) 833e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek if (HandleDecl(*DGI)) 84771fe16a5e5cbd80902f44b1286985654ffec751Ted Kremenek return; 853e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek } 863e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek 873e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek RawVAPtr = 0; 883e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek} 893e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek 903e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenekbool StmtIteratorBase::HandleDecl(Decl* D) { 911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (VarDecl* VD = dyn_cast<VarDecl>(D)) { 93f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { 943e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek setVAPtr(VAPtr); 953e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek return true; 96771fe16a5e5cbd80902f44b1286985654ffec751Ted Kremenek } 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 983e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek if (VD->getInit()) 993e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek return true; 100c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek } 101162e1c1b487352434552147967c3dd296ebee2f7Richard Smith else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) { 102f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall if (const VariableArrayType* VAPtr = 1033e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek FindVA(TD->getUnderlyingType().getTypePtr())) { 1043e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek setVAPtr(VAPtr); 1053e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek return true; 1063e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek } 1073e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek } 1083e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) { 1093e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek if (ECD->getInitExpr()) 1103e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek return true; 111103a1b45a9167ced1816101d9fb198848f05e2e4Ted Kremenek } 1123e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return false; 11492866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek} 11592866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek 11635628d1f17c817f8c240208db7ba490e3109981bTed KremenekStmtIteratorBase::StmtIteratorBase(Decl *d, Stmt **s) 11735628d1f17c817f8c240208db7ba490e3109981bTed Kremenek : stmt(s), decl(d), RawVAPtr(d ? DeclMode : 0) { 11835628d1f17c817f8c240208db7ba490e3109981bTed Kremenek if (decl) 11935628d1f17c817f8c240208db7ba490e3109981bTed Kremenek NextDecl(false); 120c7c326ad0c407dbd2a406de0f961283a790f8725Ted Kremenek} 1219caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek 1223e6d1203b3346147cee51a8a6d374f1867f2cd23Ted KremenekStmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) 123b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { 1243e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek NextDecl(false); 1253e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek} 1263e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek 127f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCallStmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) 128b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek : stmt(0), decl(0), RawVAPtr(SizeOfTypeVAMode) { 129699e9fbeae34cdd651b8e6308649c8939f090cbdTed Kremenek RawVAPtr |= reinterpret_cast<uintptr_t>(t); 130699e9fbeae34cdd651b8e6308649c8939f090cbdTed Kremenek} 131699e9fbeae34cdd651b8e6308649c8939f090cbdTed Kremenek 132b990f1834b4ba1c8e67ace010b0f554d0e59c1eaTed KremenekStmt*& StmtIteratorBase::GetDeclExpr() const { 1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 134f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall if (const VariableArrayType* VAPtr = getVAPtr()) { 13592866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek assert (VAPtr->SizeExpr); 136f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall return const_cast<Stmt*&>(VAPtr->SizeExpr); 137b990f1834b4ba1c8e67ace010b0f554d0e59c1eaTed Kremenek } 138344d4c8726e5fb7dfac42eeaef2c0df02d2059b0Ted Kremenek 139344d4c8726e5fb7dfac42eeaef2c0df02d2059b0Ted Kremenek assert (inDecl() || inDeclGroup()); 1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 141344d4c8726e5fb7dfac42eeaef2c0df02d2059b0Ted Kremenek if (inDeclGroup()) { 142344d4c8726e5fb7dfac42eeaef2c0df02d2059b0Ted Kremenek VarDecl* VD = cast<VarDecl>(*DGI); 14378d1583d0b36b7d6d8d10234cdc19ab94adf765aDouglas Gregor return *VD->getInitAddress(); 144344d4c8726e5fb7dfac42eeaef2c0df02d2059b0Ted Kremenek } 1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1463e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek assert (inDecl()); 14792866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek 14892866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek if (VarDecl* VD = dyn_cast<VarDecl>(decl)) { 14992866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek assert (VD->Init); 15078d1583d0b36b7d6d8d10234cdc19ab94adf765aDouglas Gregor return *VD->getInitAddress(); 15192866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek } 15292866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek 15392866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl); 154b3064041583eb134fbf56906728bf752bc65b572Ted Kremenek return ECD->Init; 1559caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek} 156