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