[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