Home | History | Annotate | Line # | Download | only in Sema
      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 DestroyedOrNull = E->getDestroyedType();
     71     if (!DestroyedOrNull.isNull()) {
     72       QualType Destroyed = S.Context.getBaseElementType(DestroyedOrNull);
     73       if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
     74         CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
     75         asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Record));
     76       }
     77     }
     78 
     79     Inherited::VisitCXXDeleteExpr(E);
     80   }
     81 
     82   void VisitCXXConstructExpr(CXXConstructExpr *E) {
     83     asImpl().visitUsedDecl(E->getBeginLoc(), E->getConstructor());
     84     Inherited::VisitCXXConstructExpr(E);
     85   }
     86 
     87   void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
     88     asImpl().Visit(E->getExpr());
     89   }
     90 
     91   void visitUsedDecl(SourceLocation Loc, Decl *D) {
     92     if (auto *CD = dyn_cast<CapturedDecl>(D)) {
     93       if (auto *S = CD->getBody()) {
     94         asImpl().Visit(S);
     95       }
     96     } else if (auto *CD = dyn_cast<BlockDecl>(D)) {
     97       if (auto *S = CD->getBody()) {
     98         asImpl().Visit(S);
     99       }
    100     }
    101   }
    102 };
    103 } // end namespace clang
    104 
    105 #endif // LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
    106