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