UsedDeclVisitor.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //===- UsedDeclVisitor.h - ODR-used declarations visitor --------*- C++ -*-===//
  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. // This file defines UsedDeclVisitor, a CRTP class which visits all the
  9. // declarations that are ODR-used by an expression or statement.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
  13. #define LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
  14. #include "clang/AST/EvaluatedExprVisitor.h"
  15. #include "clang/Sema/SemaInternal.h"
  16. namespace clang {
  17. template <class Derived>
  18. class UsedDeclVisitor : public EvaluatedExprVisitor<Derived> {
  19. protected:
  20. Sema &S;
  21. public:
  22. typedef EvaluatedExprVisitor<Derived> Inherited;
  23. UsedDeclVisitor(Sema &S) : Inherited(S.Context), S(S) {}
  24. Derived &asImpl() { return *static_cast<Derived *>(this); }
  25. void VisitDeclRefExpr(DeclRefExpr *E) {
  26. auto *D = E->getDecl();
  27. if (isa<FunctionDecl>(D) || isa<VarDecl>(D)) {
  28. asImpl().visitUsedDecl(E->getLocation(), D);
  29. }
  30. }
  31. void VisitMemberExpr(MemberExpr *E) {
  32. auto *D = E->getMemberDecl();
  33. if (isa<FunctionDecl>(D) || isa<VarDecl>(D)) {
  34. asImpl().visitUsedDecl(E->getMemberLoc(), D);
  35. }
  36. asImpl().Visit(E->getBase());
  37. }
  38. void VisitCapturedStmt(CapturedStmt *Node) {
  39. asImpl().visitUsedDecl(Node->getBeginLoc(), Node->getCapturedDecl());
  40. Inherited::VisitCapturedStmt(Node);
  41. }
  42. void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
  43. asImpl().visitUsedDecl(
  44. E->getBeginLoc(),
  45. const_cast<CXXDestructorDecl *>(E->getTemporary()->getDestructor()));
  46. asImpl().Visit(E->getSubExpr());
  47. }
  48. void VisitCXXNewExpr(CXXNewExpr *E) {
  49. if (E->getOperatorNew())
  50. asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorNew());
  51. if (E->getOperatorDelete())
  52. asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorDelete());
  53. Inherited::VisitCXXNewExpr(E);
  54. }
  55. void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
  56. if (E->getOperatorDelete())
  57. asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorDelete());
  58. QualType DestroyedOrNull = E->getDestroyedType();
  59. if (!DestroyedOrNull.isNull()) {
  60. QualType Destroyed = S.Context.getBaseElementType(DestroyedOrNull);
  61. if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
  62. CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
  63. if (Record->getDefinition())
  64. asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Record));
  65. }
  66. }
  67. Inherited::VisitCXXDeleteExpr(E);
  68. }
  69. void VisitCXXConstructExpr(CXXConstructExpr *E) {
  70. asImpl().visitUsedDecl(E->getBeginLoc(), E->getConstructor());
  71. CXXConstructorDecl *D = E->getConstructor();
  72. for (const CXXCtorInitializer *Init : D->inits()) {
  73. if (Init->isInClassMemberInitializer())
  74. asImpl().Visit(Init->getInit());
  75. }
  76. Inherited::VisitCXXConstructExpr(E);
  77. }
  78. void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
  79. asImpl().Visit(E->getExpr());
  80. Inherited::VisitCXXDefaultArgExpr(E);
  81. }
  82. void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
  83. asImpl().Visit(E->getExpr());
  84. Inherited::VisitCXXDefaultInitExpr(E);
  85. }
  86. void VisitInitListExpr(InitListExpr *ILE) {
  87. if (ILE->hasArrayFiller())
  88. asImpl().Visit(ILE->getArrayFiller());
  89. Inherited::VisitInitListExpr(ILE);
  90. }
  91. void visitUsedDecl(SourceLocation Loc, Decl *D) {
  92. if (auto *CD = dyn_cast<CapturedDecl>(D)) {
  93. if (auto *S = CD->getBody()) {
  94. asImpl().Visit(S);
  95. }
  96. } else if (auto *CD = dyn_cast<BlockDecl>(D)) {
  97. if (auto *S = CD->getBody()) {
  98. asImpl().Visit(S);
  99. }
  100. }
  101. }
  102. };
  103. } // end namespace clang
  104. #endif // LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H