UsedDeclVisitor.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. Inherited::VisitCXXConstructExpr(E);
  72. }
  73. void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
  74. asImpl().Visit(E->getExpr());
  75. }
  76. void visitUsedDecl(SourceLocation Loc, Decl *D) {
  77. if (auto *CD = dyn_cast<CapturedDecl>(D)) {
  78. if (auto *S = CD->getBody()) {
  79. asImpl().Visit(S);
  80. }
  81. } else if (auto *CD = dyn_cast<BlockDecl>(D)) {
  82. if (auto *S = CD->getBody()) {
  83. asImpl().Visit(S);
  84. }
  85. }
  86. }
  87. };
  88. } // end namespace clang
  89. #endif // LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H