[clang] 08ab8c9 - [NFC] Add UsedDeclVisitor
Yaxun Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 17 09:13:42 PDT 2020
Author: Yaxun (Sam) Liu
Date: 2020-03-17T12:12:40-04:00
New Revision: 08ab8c9af4dd27cb306b449edc9a9c50ed11194a
URL: https://github.com/llvm/llvm-project/commit/08ab8c9af4dd27cb306b449edc9a9c50ed11194a
DIFF: https://github.com/llvm/llvm-project/commit/08ab8c9af4dd27cb306b449edc9a9c50ed11194a.diff
LOG: [NFC] Add UsedDeclVisitor
Differential Revision: https://reviews.llvm.org/D76262
Added:
clang/lib/Sema/UsedDeclVisitor.h
Modified:
clang/lib/Sema/SemaExpr.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c1bfb962677a..e6afe7a5b421 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "TreeTransform.h"
+#include "UsedDeclVisitor.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
@@ -17400,71 +17401,33 @@ void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {
}
namespace {
- /// Helper class that marks all of the declarations referenced by
- /// potentially-evaluated subexpressions as "referenced".
- class EvaluatedExprMarker : public EvaluatedExprVisitor<EvaluatedExprMarker> {
- Sema &S;
- bool SkipLocalVariables;
-
- public:
- typedef EvaluatedExprVisitor<EvaluatedExprMarker> Inherited;
-
- EvaluatedExprMarker(Sema &S, bool SkipLocalVariables)
- : Inherited(S.Context), S(S), SkipLocalVariables(SkipLocalVariables) { }
-
- void VisitDeclRefExpr(DeclRefExpr *E) {
- // If we were asked not to visit local variables, don't.
- if (SkipLocalVariables) {
- if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
- if (VD->hasLocalStorage())
- return;
- }
-
- S.MarkDeclRefReferenced(E);
- }
-
- void VisitMemberExpr(MemberExpr *E) {
- S.MarkMemberReferenced(E);
- Inherited::VisitMemberExpr(E);
- }
-
- void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- S.MarkFunctionReferenced(
- E->getBeginLoc(),
- const_cast<CXXDestructorDecl *>(E->getTemporary()->getDestructor()));
- Visit(E->getSubExpr());
- }
+/// Helper class that marks all of the declarations referenced by
+/// potentially-evaluated subexpressions as "referenced".
+class EvaluatedExprMarker : public UsedDeclVisitor<EvaluatedExprMarker> {
+public:
+ typedef UsedDeclVisitor<EvaluatedExprMarker> Inherited;
+ bool SkipLocalVariables;
- void VisitCXXNewExpr(CXXNewExpr *E) {
- if (E->getOperatorNew())
- S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorNew());
- if (E->getOperatorDelete())
- S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorDelete());
- Inherited::VisitCXXNewExpr(E);
- }
+ EvaluatedExprMarker(Sema &S, bool SkipLocalVariables)
+ : Inherited(S), SkipLocalVariables(SkipLocalVariables) {}
- void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
- if (E->getOperatorDelete())
- S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorDelete());
- QualType Destroyed = S.Context.getBaseElementType(E->getDestroyedType());
- if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
- S.MarkFunctionReferenced(E->getBeginLoc(), S.LookupDestructor(Record));
- }
-
- Inherited::VisitCXXDeleteExpr(E);
- }
+ void visitUsedDecl(SourceLocation Loc, Decl *D) {
+ S.MarkFunctionReferenced(Loc, cast<FunctionDecl>(D));
+ }
- void VisitCXXConstructExpr(CXXConstructExpr *E) {
- S.MarkFunctionReferenced(E->getBeginLoc(), E->getConstructor());
- Inherited::VisitCXXConstructExpr(E);
+ void VisitDeclRefExpr(DeclRefExpr *E) {
+ // If we were asked not to visit local variables, don't.
+ if (SkipLocalVariables) {
+ if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
+ if (VD->hasLocalStorage())
+ return;
}
+ S.MarkDeclRefReferenced(E);
+ }
- void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
- Visit(E->getExpr());
- }
- };
-}
+ void VisitMemberExpr(MemberExpr *E) { S.MarkMemberReferenced(E); }
+};
+} // namespace
/// Mark any declarations that appear within this expression or any
/// potentially-evaluated subexpressions as "referenced".
diff --git a/clang/lib/Sema/UsedDeclVisitor.h b/clang/lib/Sema/UsedDeclVisitor.h
new file mode 100644
index 000000000000..be46f0d4affc
--- /dev/null
+++ b/clang/lib/Sema/UsedDeclVisitor.h
@@ -0,0 +1,90 @@
+//===- 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());
+ }
+};
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_SEMA_USEDDECLVISITOR_H
More information about the cfe-commits
mailing list