xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/UsedDeclVisitor.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
15ffd83dbSDimitry Andric //===- UsedDeclVisitor.h - ODR-used declarations visitor --------*- C++ -*-===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
75ffd83dbSDimitry Andric //
85ffd83dbSDimitry Andric //  This file defines UsedDeclVisitor, a CRTP class which visits all the
95ffd83dbSDimitry Andric //  declarations that are ODR-used by an expression or statement.
105ffd83dbSDimitry Andric //
115ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
125ffd83dbSDimitry Andric 
135ffd83dbSDimitry Andric #ifndef LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
145ffd83dbSDimitry Andric #define LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
155ffd83dbSDimitry Andric 
165ffd83dbSDimitry Andric #include "clang/AST/EvaluatedExprVisitor.h"
175ffd83dbSDimitry Andric #include "clang/Sema/SemaInternal.h"
185ffd83dbSDimitry Andric 
195ffd83dbSDimitry Andric namespace clang {
205ffd83dbSDimitry Andric template <class Derived>
215ffd83dbSDimitry Andric class UsedDeclVisitor : public EvaluatedExprVisitor<Derived> {
225ffd83dbSDimitry Andric protected:
235ffd83dbSDimitry Andric   Sema &S;
245ffd83dbSDimitry Andric 
255ffd83dbSDimitry Andric public:
265ffd83dbSDimitry Andric   typedef EvaluatedExprVisitor<Derived> Inherited;
275ffd83dbSDimitry Andric 
UsedDeclVisitor(Sema & S)285ffd83dbSDimitry Andric   UsedDeclVisitor(Sema &S) : Inherited(S.Context), S(S) {}
295ffd83dbSDimitry Andric 
asImpl()305ffd83dbSDimitry Andric   Derived &asImpl() { return *static_cast<Derived *>(this); }
315ffd83dbSDimitry Andric 
VisitDeclRefExpr(DeclRefExpr * E)325ffd83dbSDimitry Andric   void VisitDeclRefExpr(DeclRefExpr *E) {
335ffd83dbSDimitry Andric     auto *D = E->getDecl();
345ffd83dbSDimitry Andric     if (isa<FunctionDecl>(D) || isa<VarDecl>(D)) {
355ffd83dbSDimitry Andric       asImpl().visitUsedDecl(E->getLocation(), D);
365ffd83dbSDimitry Andric     }
375ffd83dbSDimitry Andric   }
385ffd83dbSDimitry Andric 
VisitMemberExpr(MemberExpr * E)395ffd83dbSDimitry Andric   void VisitMemberExpr(MemberExpr *E) {
405ffd83dbSDimitry Andric     auto *D = E->getMemberDecl();
415ffd83dbSDimitry Andric     if (isa<FunctionDecl>(D) || isa<VarDecl>(D)) {
425ffd83dbSDimitry Andric       asImpl().visitUsedDecl(E->getMemberLoc(), D);
435ffd83dbSDimitry Andric     }
445ffd83dbSDimitry Andric     asImpl().Visit(E->getBase());
455ffd83dbSDimitry Andric   }
465ffd83dbSDimitry Andric 
VisitCapturedStmt(CapturedStmt * Node)475ffd83dbSDimitry Andric   void VisitCapturedStmt(CapturedStmt *Node) {
485ffd83dbSDimitry Andric     asImpl().visitUsedDecl(Node->getBeginLoc(), Node->getCapturedDecl());
495ffd83dbSDimitry Andric     Inherited::VisitCapturedStmt(Node);
505ffd83dbSDimitry Andric   }
515ffd83dbSDimitry Andric 
VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr * E)525ffd83dbSDimitry Andric   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
535ffd83dbSDimitry Andric     asImpl().visitUsedDecl(
545ffd83dbSDimitry Andric         E->getBeginLoc(),
555ffd83dbSDimitry Andric         const_cast<CXXDestructorDecl *>(E->getTemporary()->getDestructor()));
565ffd83dbSDimitry Andric     asImpl().Visit(E->getSubExpr());
575ffd83dbSDimitry Andric   }
585ffd83dbSDimitry Andric 
VisitCXXNewExpr(CXXNewExpr * E)595ffd83dbSDimitry Andric   void VisitCXXNewExpr(CXXNewExpr *E) {
605ffd83dbSDimitry Andric     if (E->getOperatorNew())
615ffd83dbSDimitry Andric       asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorNew());
625ffd83dbSDimitry Andric     if (E->getOperatorDelete())
635ffd83dbSDimitry Andric       asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorDelete());
645ffd83dbSDimitry Andric     Inherited::VisitCXXNewExpr(E);
655ffd83dbSDimitry Andric   }
665ffd83dbSDimitry Andric 
VisitCXXDeleteExpr(CXXDeleteExpr * E)675ffd83dbSDimitry Andric   void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
685ffd83dbSDimitry Andric     if (E->getOperatorDelete())
695ffd83dbSDimitry Andric       asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorDelete());
70eaeb601bSDimitry Andric     QualType DestroyedOrNull = E->getDestroyedType();
71eaeb601bSDimitry Andric     if (!DestroyedOrNull.isNull()) {
72eaeb601bSDimitry Andric       QualType Destroyed = S.Context.getBaseElementType(DestroyedOrNull);
735ffd83dbSDimitry Andric       if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
745ffd83dbSDimitry Andric         CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
75349cc55cSDimitry Andric         if (Record->getDefinition())
765ffd83dbSDimitry Andric           asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Record));
775ffd83dbSDimitry Andric       }
78eaeb601bSDimitry Andric     }
795ffd83dbSDimitry Andric 
805ffd83dbSDimitry Andric     Inherited::VisitCXXDeleteExpr(E);
815ffd83dbSDimitry Andric   }
825ffd83dbSDimitry Andric 
VisitCXXConstructExpr(CXXConstructExpr * E)835ffd83dbSDimitry Andric   void VisitCXXConstructExpr(CXXConstructExpr *E) {
845ffd83dbSDimitry Andric     asImpl().visitUsedDecl(E->getBeginLoc(), E->getConstructor());
85*bdd1243dSDimitry Andric     CXXConstructorDecl *D = E->getConstructor();
86*bdd1243dSDimitry Andric     for (const CXXCtorInitializer *Init : D->inits()) {
87*bdd1243dSDimitry Andric       if (Init->isInClassMemberInitializer())
88*bdd1243dSDimitry Andric         asImpl().Visit(Init->getInit());
89*bdd1243dSDimitry Andric     }
905ffd83dbSDimitry Andric     Inherited::VisitCXXConstructExpr(E);
915ffd83dbSDimitry Andric   }
925ffd83dbSDimitry Andric 
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * E)935ffd83dbSDimitry Andric   void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
945ffd83dbSDimitry Andric     asImpl().Visit(E->getExpr());
95*bdd1243dSDimitry Andric     Inherited::VisitCXXDefaultArgExpr(E);
96*bdd1243dSDimitry Andric   }
97*bdd1243dSDimitry Andric 
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * E)98*bdd1243dSDimitry Andric   void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
99*bdd1243dSDimitry Andric     asImpl().Visit(E->getExpr());
100*bdd1243dSDimitry Andric     Inherited::VisitCXXDefaultInitExpr(E);
101*bdd1243dSDimitry Andric   }
102*bdd1243dSDimitry Andric 
VisitInitListExpr(InitListExpr * ILE)103*bdd1243dSDimitry Andric   void VisitInitListExpr(InitListExpr *ILE) {
104*bdd1243dSDimitry Andric     if (ILE->hasArrayFiller())
105*bdd1243dSDimitry Andric       asImpl().Visit(ILE->getArrayFiller());
106*bdd1243dSDimitry Andric     Inherited::VisitInitListExpr(ILE);
1075ffd83dbSDimitry Andric   }
1085ffd83dbSDimitry Andric 
visitUsedDecl(SourceLocation Loc,Decl * D)1095ffd83dbSDimitry Andric   void visitUsedDecl(SourceLocation Loc, Decl *D) {
1105ffd83dbSDimitry Andric     if (auto *CD = dyn_cast<CapturedDecl>(D)) {
1115ffd83dbSDimitry Andric       if (auto *S = CD->getBody()) {
1125ffd83dbSDimitry Andric         asImpl().Visit(S);
1135ffd83dbSDimitry Andric       }
1145ffd83dbSDimitry Andric     } else if (auto *CD = dyn_cast<BlockDecl>(D)) {
1155ffd83dbSDimitry Andric       if (auto *S = CD->getBody()) {
1165ffd83dbSDimitry Andric         asImpl().Visit(S);
1175ffd83dbSDimitry Andric       }
1185ffd83dbSDimitry Andric     }
1195ffd83dbSDimitry Andric   }
1205ffd83dbSDimitry Andric };
1215ffd83dbSDimitry Andric } // end namespace clang
1225ffd83dbSDimitry Andric 
1235ffd83dbSDimitry Andric #endif // LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
124