123 lines · c
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-exception6//===----------------------------------------------------------------------===//7//8// This file defines UsedDeclVisitor, a CRTP class which visits all the9// declarations that are ODR-used by an expression or statement.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H14#define LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H15 16#include "clang/AST/EvaluatedExprVisitor.h"17#include "clang/Sema/SemaInternal.h"18 19namespace clang {20template <class Derived>21class UsedDeclVisitor : public EvaluatedExprVisitor<Derived> {22protected:23 Sema &S;24 25public: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 DestroyedOrNull = E->getDestroyedType();71 if (!DestroyedOrNull.isNull()) {72 QualType Destroyed = S.Context.getBaseElementType(DestroyedOrNull);73 if (auto *Record = Destroyed->getAsCXXRecordDecl();74 Record &&75 (Record->isBeingDefined() || Record->isCompleteDefinition()))76 asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Record));77 }78 79 Inherited::VisitCXXDeleteExpr(E);80 }81 82 void VisitCXXConstructExpr(CXXConstructExpr *E) {83 asImpl().visitUsedDecl(E->getBeginLoc(), E->getConstructor());84 CXXConstructorDecl *D = E->getConstructor();85 for (const CXXCtorInitializer *Init : D->inits()) {86 if (Init->isInClassMemberInitializer())87 asImpl().Visit(Init->getInit());88 }89 Inherited::VisitCXXConstructExpr(E);90 }91 92 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {93 asImpl().Visit(E->getExpr());94 Inherited::VisitCXXDefaultArgExpr(E);95 }96 97 void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {98 asImpl().Visit(E->getExpr());99 Inherited::VisitCXXDefaultInitExpr(E);100 }101 102 void VisitInitListExpr(InitListExpr *ILE) {103 if (ILE->hasArrayFiller())104 asImpl().Visit(ILE->getArrayFiller());105 Inherited::VisitInitListExpr(ILE);106 }107 108 void visitUsedDecl(SourceLocation Loc, Decl *D) {109 if (auto *CD = dyn_cast<CapturedDecl>(D)) {110 if (auto *S = CD->getBody()) {111 asImpl().Visit(S);112 }113 } else if (auto *CD = dyn_cast<BlockDecl>(D)) {114 if (auto *S = CD->getBody()) {115 asImpl().Visit(S);116 }117 }118 }119};120} // end namespace clang121 122#endif // LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H123