StmtIterator.cpp 2.9 KB

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