StmtIterator.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines internal methods for StmtIterator.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/AST/StmtIterator.h"
  14. #include "clang/AST/Decl.h"
  15. using namespace clang;
  16. // FIXME: Add support for dependent-sized array types in C++?
  17. // Does it even make sense to build a CFG for an uninstantiated template?
  18. static inline const VariableArrayType *FindVA(const Type* t) {
  19. while (const ArrayType *vt = dyn_cast<ArrayType>(t)) {
  20. if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt))
  21. if (vat->getSizeExpr())
  22. return vat;
  23. t = vt->getElementType().getTypePtr();
  24. }
  25. return nullptr;
  26. }
  27. void StmtIteratorBase::NextVA() {
  28. assert (getVAPtr());
  29. const VariableArrayType *p = getVAPtr();
  30. p = FindVA(p->getElementType().getTypePtr());
  31. setVAPtr(p);
  32. if (p)
  33. return;
  34. if (inDeclGroup()) {
  35. if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
  36. if (VD->Init)
  37. return;
  38. NextDecl();
  39. }
  40. else {
  41. assert(inSizeOfTypeVA());
  42. RawVAPtr = 0;
  43. }
  44. }
  45. void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
  46. assert(getVAPtr() == nullptr);
  47. assert(inDeclGroup());
  48. if (ImmediateAdvance)
  49. ++DGI;
  50. for ( ; DGI != DGE; ++DGI)
  51. if (HandleDecl(*DGI))
  52. return;
  53. RawVAPtr = 0;
  54. }
  55. bool StmtIteratorBase::HandleDecl(Decl* D) {
  56. if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
  57. if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
  58. setVAPtr(VAPtr);
  59. return true;
  60. }
  61. if (VD->getInit())
  62. return true;
  63. }
  64. else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) {
  65. if (const VariableArrayType* VAPtr =
  66. FindVA(TD->getUnderlyingType().getTypePtr())) {
  67. setVAPtr(VAPtr);
  68. return true;
  69. }
  70. }
  71. else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
  72. if (ECD->getInitExpr())
  73. return true;
  74. }
  75. return false;
  76. }
  77. StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
  78. : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
  79. NextDecl(false);
  80. }
  81. StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
  82. : DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
  83. RawVAPtr |= reinterpret_cast<uintptr_t>(t);
  84. }
  85. Stmt*& StmtIteratorBase::GetDeclExpr() const {
  86. if (const VariableArrayType* VAPtr = getVAPtr()) {
  87. assert (VAPtr->SizeExpr);
  88. return const_cast<Stmt*&>(VAPtr->SizeExpr);
  89. }
  90. assert (inDeclGroup());
  91. VarDecl* VD = cast<VarDecl>(*DGI);
  92. return *VD->getInitAddress();
  93. }