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