diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
| commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
| tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Sema/UsedDeclVisitor.h | |
| parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
Notes
Diffstat (limited to 'clang/lib/Sema/UsedDeclVisitor.h')
| -rw-r--r-- | clang/lib/Sema/UsedDeclVisitor.h | 102 | 
1 files changed, 102 insertions, 0 deletions
diff --git a/clang/lib/Sema/UsedDeclVisitor.h b/clang/lib/Sema/UsedDeclVisitor.h new file mode 100644 index 000000000000..d207e07f451a --- /dev/null +++ b/clang/lib/Sema/UsedDeclVisitor.h @@ -0,0 +1,102 @@ +//===- 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 Destroyed = S.Context.getBaseElementType(E->getDestroyedType()); +    if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { +      CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); +      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  | 
