Skip to content

Commit 9ec8c96

Browse files
authored
[clang][dataflow] Expose getReferencedDecls and relocate free functions. (#88754)
Moves free functions from DataflowEnvironment.h/cc and DataflowAnalysisContext.h/cc to RecordOps and a new ASTOps and exposes them as needed for current use and to expose getReferencedDecls for out-of-tree use. Minimal change in functionality, only to modify the return type of getReferenceDecls to return the collected decls instead of using output params. Tested with `ninja check-clang-tooling`.
1 parent b01879e commit 9ec8c96

File tree

9 files changed

+359
-287
lines changed

9 files changed

+359
-287
lines changed

clang/docs/tools/clang-formatted-files.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ clang/include/clang/Analysis/Analyses/CalledOnceCheck.h
123123
clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
124124
clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
125125
clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h
126+
clang/include/clang/Analysis/FlowSensitive/ASTOps.h
126127
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
127128
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
128129
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -307,6 +308,7 @@ clang/lib/Analysis/CalledOnceCheck.cpp
307308
clang/lib/Analysis/CloneDetection.cpp
308309
clang/lib/Analysis/CodeInjector.cpp
309310
clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
311+
clang/lib/Analysis/FlowSensitive/ASTOps.cpp
310312
clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
311313
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
312314
clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//===-- ASTOps.h -------------------------------*- 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+
//
9+
// Operations on AST nodes that are used in flow-sensitive analysis.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
14+
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
15+
16+
#include "clang/AST/Decl.h"
17+
#include "clang/AST/Expr.h"
18+
#include "clang/AST/Type.h"
19+
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
20+
#include "llvm/ADT/DenseSet.h"
21+
#include "llvm/ADT/SetVector.h"
22+
23+
namespace clang {
24+
namespace dataflow {
25+
26+
/// Skip past nodes that the CFG does not emit. These nodes are invisible to
27+
/// flow-sensitive analysis, and should be ignored as they will effectively not
28+
/// exist.
29+
///
30+
/// * `ParenExpr` - The CFG takes the operator precedence into account, but
31+
/// otherwise omits the node afterwards.
32+
///
33+
/// * `ExprWithCleanups` - The CFG will generate the appropriate calls to
34+
/// destructors and then omit the node.
35+
///
36+
const Expr &ignoreCFGOmittedNodes(const Expr &E);
37+
const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
38+
39+
/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
40+
/// iteration order.
41+
using FieldSet = llvm::SmallSetVector<const FieldDecl *, 4>;
42+
43+
/// Returns the set of all fields in the type.
44+
FieldSet getObjectFields(QualType Type);
45+
46+
/// Returns whether `Fields` and `FieldLocs` contain the same fields.
47+
bool containsSameFields(const FieldSet &Fields,
48+
const RecordStorageLocation::FieldToLoc &FieldLocs);
49+
50+
/// Helper class for initialization of a record with an `InitListExpr`.
51+
/// `InitListExpr::inits()` contains the initializers for both the base classes
52+
/// and the fields of the record; this helper class separates these out into two
53+
/// different lists. In addition, it deals with special cases associated with
54+
/// unions.
55+
class RecordInitListHelper {
56+
public:
57+
// `InitList` must have record type.
58+
RecordInitListHelper(const InitListExpr *InitList);
59+
60+
// Base classes with their associated initializer expressions.
61+
ArrayRef<std::pair<const CXXBaseSpecifier *, Expr *>> base_inits() const {
62+
return BaseInits;
63+
}
64+
65+
// Fields with their associated initializer expressions.
66+
ArrayRef<std::pair<const FieldDecl *, Expr *>> field_inits() const {
67+
return FieldInits;
68+
}
69+
70+
private:
71+
SmallVector<std::pair<const CXXBaseSpecifier *, Expr *>> BaseInits;
72+
SmallVector<std::pair<const FieldDecl *, Expr *>> FieldInits;
73+
74+
// We potentially synthesize an `ImplicitValueInitExpr` for unions. It's a
75+
// member variable because we store a pointer to it in `FieldInits`.
76+
std::optional<ImplicitValueInitExpr> ImplicitValueInitForUnion;
77+
};
78+
79+
/// A collection of several types of declarations, all referenced from the same
80+
/// function.
81+
struct ReferencedDecls {
82+
/// Non-static member variables.
83+
FieldSet Fields;
84+
/// All variables with static storage duration, notably including static
85+
/// member variables and static variables declared within a function.
86+
llvm::DenseSet<const VarDecl *> Globals;
87+
/// Free functions and member functions which are referenced (but not
88+
/// necessarily called).
89+
llvm::DenseSet<const FunctionDecl *> Functions;
90+
};
91+
92+
/// Returns declarations that are declared in or referenced from `FD`.
93+
ReferencedDecls getReferencedDecls(const FunctionDecl &FD);
94+
95+
} // namespace dataflow
96+
} // namespace clang
97+
98+
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H

clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/AST/Decl.h"
1919
#include "clang/AST/Expr.h"
2020
#include "clang/AST/TypeOrdering.h"
21+
#include "clang/Analysis/FlowSensitive/ASTOps.h"
2122
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
2223
#include "clang/Analysis/FlowSensitive/Arena.h"
2324
#include "clang/Analysis/FlowSensitive/Solver.h"
@@ -30,38 +31,11 @@
3031
#include <cassert>
3132
#include <memory>
3233
#include <optional>
33-
#include <type_traits>
34-
#include <utility>
35-
#include <vector>
3634

3735
namespace clang {
3836
namespace dataflow {
3937
class Logger;
4038

41-
/// Skip past nodes that the CFG does not emit. These nodes are invisible to
42-
/// flow-sensitive analysis, and should be ignored as they will effectively not
43-
/// exist.
44-
///
45-
/// * `ParenExpr` - The CFG takes the operator precedence into account, but
46-
/// otherwise omits the node afterwards.
47-
///
48-
/// * `ExprWithCleanups` - The CFG will generate the appropriate calls to
49-
/// destructors and then omit the node.
50-
///
51-
const Expr &ignoreCFGOmittedNodes(const Expr &E);
52-
const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
53-
54-
/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
55-
/// iteration order.
56-
using FieldSet = llvm::SmallSetVector<const FieldDecl *, 4>;
57-
58-
/// Returns the set of all fields in the type.
59-
FieldSet getObjectFields(QualType Type);
60-
61-
/// Returns whether `Fields` and `FieldLocs` contain the same fields.
62-
bool containsSameFields(const FieldSet &Fields,
63-
const RecordStorageLocation::FieldToLoc &FieldLocs);
64-
6539
struct ContextSensitiveOptions {
6640
/// The maximum depth to analyze. A value of zero is equivalent to disabling
6741
/// context-sensitive analysis entirely.

clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -775,42 +775,6 @@ RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE,
775775
RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
776776
const Environment &Env);
777777

778-
/// Returns the fields of a `RecordDecl` that are initialized by an
779-
/// `InitListExpr`, in the order in which they appear in
780-
/// `InitListExpr::inits()`.
781-
/// `Init->getType()` must be a record type.
782-
std::vector<const FieldDecl *>
783-
getFieldsForInitListExpr(const InitListExpr *InitList);
784-
785-
/// Helper class for initialization of a record with an `InitListExpr`.
786-
/// `InitListExpr::inits()` contains the initializers for both the base classes
787-
/// and the fields of the record; this helper class separates these out into two
788-
/// different lists. In addition, it deals with special cases associated with
789-
/// unions.
790-
class RecordInitListHelper {
791-
public:
792-
// `InitList` must have record type.
793-
RecordInitListHelper(const InitListExpr *InitList);
794-
795-
// Base classes with their associated initializer expressions.
796-
ArrayRef<std::pair<const CXXBaseSpecifier *, Expr *>> base_inits() const {
797-
return BaseInits;
798-
}
799-
800-
// Fields with their associated initializer expressions.
801-
ArrayRef<std::pair<const FieldDecl *, Expr *>> field_inits() const {
802-
return FieldInits;
803-
}
804-
805-
private:
806-
SmallVector<std::pair<const CXXBaseSpecifier *, Expr *>> BaseInits;
807-
SmallVector<std::pair<const FieldDecl *, Expr *>> FieldInits;
808-
809-
// We potentially synthesize an `ImplicitValueInitExpr` for unions. It's a
810-
// member variable because we store a pointer to it in `FieldInits`.
811-
std::optional<ImplicitValueInitExpr> ImplicitValueInitForUnion;
812-
};
813-
814778
/// Associates a new `RecordValue` with `Loc` and returns the new value.
815779
RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env);
816780

0 commit comments

Comments
 (0)