123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- //===- UsedDeclVisitor.h - ODR-used declarations visitor --------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //===----------------------------------------------------------------------===//
- //
- // This file defines UsedDeclVisitor, a CRTP class which visits all the
- // declarations that are ODR-used by an expression or statement.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
- #define LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
- #include "clang/AST/EvaluatedExprVisitor.h"
- #include "clang/Sema/SemaInternal.h"
- namespace clang {
- template <class Derived>
- class UsedDeclVisitor : public EvaluatedExprVisitor<Derived> {
- protected:
- Sema &S;
- public:
- typedef EvaluatedExprVisitor<Derived> Inherited;
- UsedDeclVisitor(Sema &S) : Inherited(S.Context), S(S) {}
- Derived &asImpl() { return *static_cast<Derived *>(this); }
- void VisitDeclRefExpr(DeclRefExpr *E) {
- auto *D = E->getDecl();
- if (isa<FunctionDecl>(D) || isa<VarDecl>(D)) {
- asImpl().visitUsedDecl(E->getLocation(), D);
- }
- }
- void VisitMemberExpr(MemberExpr *E) {
- auto *D = E->getMemberDecl();
- if (isa<FunctionDecl>(D) || isa<VarDecl>(D)) {
- asImpl().visitUsedDecl(E->getMemberLoc(), D);
- }
- asImpl().Visit(E->getBase());
- }
- void VisitCapturedStmt(CapturedStmt *Node) {
- asImpl().visitUsedDecl(Node->getBeginLoc(), Node->getCapturedDecl());
- Inherited::VisitCapturedStmt(Node);
- }
- void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- asImpl().visitUsedDecl(
- E->getBeginLoc(),
- const_cast<CXXDestructorDecl *>(E->getTemporary()->getDestructor()));
- asImpl().Visit(E->getSubExpr());
- }
- void VisitCXXNewExpr(CXXNewExpr *E) {
- if (E->getOperatorNew())
- asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorNew());
- if (E->getOperatorDelete())
- asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorDelete());
- Inherited::VisitCXXNewExpr(E);
- }
- void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
- if (E->getOperatorDelete())
- asImpl().visitUsedDecl(E->getBeginLoc(), E->getOperatorDelete());
- QualType DestroyedOrNull = E->getDestroyedType();
- if (!DestroyedOrNull.isNull()) {
- QualType Destroyed = S.Context.getBaseElementType(DestroyedOrNull);
- if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
- if (Record->getDefinition())
- asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Record));
- }
- }
- Inherited::VisitCXXDeleteExpr(E);
- }
- void VisitCXXConstructExpr(CXXConstructExpr *E) {
- asImpl().visitUsedDecl(E->getBeginLoc(), E->getConstructor());
- Inherited::VisitCXXConstructExpr(E);
- }
- void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
- asImpl().Visit(E->getExpr());
- }
- void visitUsedDecl(SourceLocation Loc, Decl *D) {
- if (auto *CD = dyn_cast<CapturedDecl>(D)) {
- if (auto *S = CD->getBody()) {
- asImpl().Visit(S);
- }
- } else if (auto *CD = dyn_cast<BlockDecl>(D)) {
- if (auto *S = CD->getBody()) {
- asImpl().Visit(S);
- }
- }
- }
- };
- } // end namespace clang
- #endif // LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
|