[clang] [clang][ssaf] Add EntityLinkage data structure (PR #181718)
Aviral Goel via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 16 12:10:51 PST 2026
https://github.com/aviralg updated https://github.com/llvm/llvm-project/pull/181718
>From 981d4e23acaf6ec2135d52c2f7eb2d52f7833065 Mon Sep 17 00:00:00 2001
From: Aviral Goel <agoel26 at apple.com>
Date: Mon, 16 Feb 2026 10:21:09 -0800
Subject: [PATCH 1/3] Add EntityLinkage data structure and update TUSummary
---
.../Analysis/Scalable/Model/EntityLinkage.h | 50 +++++++++++++++++++
.../Scalable/Model/PrivateFieldNames.def | 2 +
.../Analysis/Scalable/TUSummary/TUSummary.h | 4 ++
.../Analysis/Scalable/CMakeLists.txt | 1 +
.../Analysis/Scalable/EntityLinkageTest.cpp | 48 ++++++++++++++++++
5 files changed, 105 insertions(+)
create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
create mode 100644 clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
diff --git a/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h b/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
new file mode 100644
index 0000000000000..8ac51007afc65
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
@@ -0,0 +1,50 @@
+//===- EntityLinkage.h ------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_ENTITYLINKAGE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_ENTITYLINKAGE_H
+
+namespace clang::ssaf {
+
+/// Represents the linkage properties of an entity in the program model.
+///
+/// EntityLinkage captures whether an entity has no linkage, internal linkage,
+/// or external linkage, which determines its visibility and accessibility
+/// across translation units.
+class EntityLinkage {
+ friend class SerializationFormat;
+
+public:
+ /// Specifies the type of linkage an entity has.
+ enum class LinkageType {
+ None, ///< No linkage (e.g., local variables, function parameters)
+ Internal, ///< Internal linkage (static functions/variables, anonymous
+ ///< namespace)
+ External ///< External linkage (globally visible across translation units)
+ };
+
+ /// Constructs an EntityLinkage with no linkage (default).
+ EntityLinkage() : Linkage(LinkageType::None) {}
+
+ /// Constructs an EntityLinkage with the specified linkage type.
+ ///
+ /// \param L The linkage type to assign to this entity.
+ explicit EntityLinkage(LinkageType L) : Linkage(L) {}
+
+ /// Returns the linkage type of this entity.
+ ///
+ /// \return The LinkageType indicating the entity's linkage.
+ LinkageType getLinkage() const { return Linkage; }
+
+private:
+ LinkageType Linkage;
+};
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_ENTITYLINKAGE_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/PrivateFieldNames.def b/clang/include/clang/Analysis/Scalable/Model/PrivateFieldNames.def
index 59064659996b4..961994f4ae455 100644
--- a/clang/include/clang/Analysis/Scalable/Model/PrivateFieldNames.def
+++ b/clang/include/clang/Analysis/Scalable/Model/PrivateFieldNames.def
@@ -19,12 +19,14 @@
FIELD(BuildNamespace, Kind)
FIELD(BuildNamespace, Name)
+FIELD(EntityLinkage, Linkage)
FIELD(EntityName, Namespace)
FIELD(EntityName, Suffix)
FIELD(EntityName, USR)
FIELD(NestedBuildNamespace, Namespaces)
FIELD(TUSummary, Data)
FIELD(TUSummary, IdTable)
+FIELD(TUSummary, LinkageTable)
FIELD(TUSummary, TUNamespace)
#undef FIELD
diff --git a/clang/include/clang/Analysis/Scalable/TUSummary/TUSummary.h b/clang/include/clang/Analysis/Scalable/TUSummary/TUSummary.h
index 4af1c70e1a488..2520ce87f3959 100644
--- a/clang/include/clang/Analysis/Scalable/TUSummary/TUSummary.h
+++ b/clang/include/clang/Analysis/Scalable/TUSummary/TUSummary.h
@@ -12,6 +12,7 @@
#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
#include "clang/Analysis/Scalable/Model/EntityId.h"
#include "clang/Analysis/Scalable/Model/EntityIdTable.h"
+#include "clang/Analysis/Scalable/Model/EntityLinkage.h"
#include "clang/Analysis/Scalable/Model/SummaryName.h"
#include "clang/Analysis/Scalable/TUSummary/EntitySummary.h"
#include <map>
@@ -23,8 +24,11 @@ namespace clang::ssaf {
class TUSummary {
/// Identifies the translation unit.
BuildNamespace TUNamespace;
+
EntityIdTable IdTable;
+ std::map<EntityId, EntityLinkage> LinkageTable;
+
std::map<SummaryName, std::map<EntityId, std::unique_ptr<EntitySummary>>>
Data;
diff --git a/clang/unittests/Analysis/Scalable/CMakeLists.txt b/clang/unittests/Analysis/Scalable/CMakeLists.txt
index 601845b4ab77a..692fb0fa58b99 100644
--- a/clang/unittests/Analysis/Scalable/CMakeLists.txt
+++ b/clang/unittests/Analysis/Scalable/CMakeLists.txt
@@ -3,6 +3,7 @@ add_distinct_clang_unittest(ClangScalableAnalysisTests
BuildNamespaceTest.cpp
EntityIdTest.cpp
EntityIdTableTest.cpp
+ EntityLinkageTest.cpp
EntityNameTest.cpp
Registries/FancyAnalysisData.cpp
Registries/MockSerializationFormat.cpp
diff --git a/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp b/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
new file mode 100644
index 0000000000000..d71cf0597d80f
--- /dev/null
+++ b/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
@@ -0,0 +1,48 @@
+//===- unittests/Analysis/Scalable/EntityLinkageTest.cpp -----------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Scalable/Model/EntityLinkage.h"
+#include "gtest/gtest.h"
+
+namespace clang::ssaf {
+
+namespace {
+
+TEST(EntityLinkageTest, GetLinkageReturnsCorrectValue) {
+ EntityLinkage Linkage;
+ EntityLinkage NoneLinkage(EntityLinkage::LinkageType::None);
+ EntityLinkage InternalLinkage(EntityLinkage::LinkageType::Internal);
+ EntityLinkage ExternalLinkage(EntityLinkage::LinkageType::External);
+
+ EXPECT_EQ(Linkage.getLinkage(), EntityLinkage::LinkageType::None);
+ EXPECT_EQ(NoneLinkage.getLinkage(), EntityLinkage::LinkageType::None);
+ EXPECT_EQ(InternalLinkage.getLinkage(), EntityLinkage::LinkageType::Internal);
+ EXPECT_EQ(ExternalLinkage.getLinkage(), EntityLinkage::LinkageType::External);
+}
+
+TEST(EntityLinkageTest, CopyConstructor) {
+ EntityLinkage Original(EntityLinkage::LinkageType::External);
+ EntityLinkage Copy = Original;
+
+ EXPECT_EQ(Copy.getLinkage(), EntityLinkage::LinkageType::External);
+ EXPECT_EQ(Copy.getLinkage(), Original.getLinkage());
+}
+
+TEST(EntityLinkageTest, AssignmentOperator) {
+ EntityLinkage Linkage1(EntityLinkage::LinkageType::None);
+ EntityLinkage Linkage2(EntityLinkage::LinkageType::External);
+
+ Linkage1 = Linkage2;
+
+ EXPECT_EQ(Linkage1.getLinkage(), EntityLinkage::LinkageType::External);
+ EXPECT_EQ(Linkage1.getLinkage(), Linkage2.getLinkage());
+}
+
+} // namespace
+
+} // namespace clang::ssaf
>From a97a70dc745963eec91b03c864da43603805aea4 Mon Sep 17 00:00:00 2001
From: Aviral Goel <agoel26 at apple.com>
Date: Mon, 16 Feb 2026 11:24:09 -0800
Subject: [PATCH 2/3] Balazs
---
.../Analysis/Scalable/Model/EntityLinkage.h | 12 +++----
.../Analysis/Scalable/EntityLinkageTest.cpp | 34 ++++++++++---------
2 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h b/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
index 8ac51007afc65..4aa5d597e1066 100644
--- a/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
+++ b/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
@@ -22,15 +22,11 @@ class EntityLinkage {
public:
/// Specifies the type of linkage an entity has.
enum class LinkageType {
- None, ///< No linkage (e.g., local variables, function parameters)
- Internal, ///< Internal linkage (static functions/variables, anonymous
- ///< namespace)
- External ///< External linkage (globally visible across translation units)
+ None, ///< local variables, function parameters
+ Internal, ///< static functions/variables, anonymous namespace
+ External ///< globally visible across translation units
};
- /// Constructs an EntityLinkage with no linkage (default).
- EntityLinkage() : Linkage(LinkageType::None) {}
-
/// Constructs an EntityLinkage with the specified linkage type.
///
/// \param L The linkage type to assign to this entity.
@@ -42,7 +38,7 @@ class EntityLinkage {
LinkageType getLinkage() const { return Linkage; }
private:
- LinkageType Linkage;
+ LinkageType Linkage = LinkageType::None;
};
} // namespace clang::ssaf
diff --git a/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp b/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
index d71cf0597d80f..0eb8ecd4fc97a 100644
--- a/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
+++ b/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
@@ -9,40 +9,42 @@
#include "clang/Analysis/Scalable/Model/EntityLinkage.h"
#include "gtest/gtest.h"
-namespace clang::ssaf {
+using clang::ssaf::EntityLinkage;
namespace {
+constexpr inline auto None = EntityLinkage::LinkageType::None;
+constexpr inline auto Internal = EntityLinkage::LinkageType::Internal;
+constexpr inline auto External = EntityLinkage::LinkageType::External;
+
TEST(EntityLinkageTest, GetLinkageReturnsCorrectValue) {
EntityLinkage Linkage;
- EntityLinkage NoneLinkage(EntityLinkage::LinkageType::None);
- EntityLinkage InternalLinkage(EntityLinkage::LinkageType::Internal);
- EntityLinkage ExternalLinkage(EntityLinkage::LinkageType::External);
-
- EXPECT_EQ(Linkage.getLinkage(), EntityLinkage::LinkageType::None);
- EXPECT_EQ(NoneLinkage.getLinkage(), EntityLinkage::LinkageType::None);
- EXPECT_EQ(InternalLinkage.getLinkage(), EntityLinkage::LinkageType::Internal);
- EXPECT_EQ(ExternalLinkage.getLinkage(), EntityLinkage::LinkageType::External);
+ EntityLinkage NoneLinkage(None);
+ EntityLinkage InternalLinkage(Internal);
+ EntityLinkage ExternalLinkage(External);
+
+ EXPECT_EQ(Linkage.getLinkage(), None);
+ EXPECT_EQ(NoneLinkage.getLinkage(), None);
+ EXPECT_EQ(InternalLinkage.getLinkage(), Internal);
+ EXPECT_EQ(ExternalLinkage.getLinkage(), External);
}
TEST(EntityLinkageTest, CopyConstructor) {
- EntityLinkage Original(EntityLinkage::LinkageType::External);
+ EntityLinkage Original(External);
EntityLinkage Copy = Original;
- EXPECT_EQ(Copy.getLinkage(), EntityLinkage::LinkageType::External);
+ EXPECT_EQ(Copy.getLinkage(), External);
EXPECT_EQ(Copy.getLinkage(), Original.getLinkage());
}
TEST(EntityLinkageTest, AssignmentOperator) {
- EntityLinkage Linkage1(EntityLinkage::LinkageType::None);
- EntityLinkage Linkage2(EntityLinkage::LinkageType::External);
+ EntityLinkage Linkage1(None);
+ EntityLinkage Linkage2(External);
Linkage1 = Linkage2;
- EXPECT_EQ(Linkage1.getLinkage(), EntityLinkage::LinkageType::External);
+ EXPECT_EQ(Linkage1.getLinkage(), External);
EXPECT_EQ(Linkage1.getLinkage(), Linkage2.getLinkage());
}
} // namespace
-
-} // namespace clang::ssaf
>From 39c958d1990475d8db61746a6626f7b29a1c40a6 Mon Sep 17 00:00:00 2001
From: Aviral Goel <agoel26 at apple.com>
Date: Mon, 16 Feb 2026 12:09:04 -0800
Subject: [PATCH 3/3] More fixes
---
.../clang/Analysis/Scalable/Model/EntityLinkage.h | 9 +--------
clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp | 4 +---
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h b/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
index 4aa5d597e1066..ba5f7d3073a30 100644
--- a/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
+++ b/clang/include/clang/Analysis/Scalable/Model/EntityLinkage.h
@@ -20,25 +20,18 @@ class EntityLinkage {
friend class SerializationFormat;
public:
- /// Specifies the type of linkage an entity has.
enum class LinkageType {
None, ///< local variables, function parameters
Internal, ///< static functions/variables, anonymous namespace
External ///< globally visible across translation units
};
- /// Constructs an EntityLinkage with the specified linkage type.
- ///
- /// \param L The linkage type to assign to this entity.
explicit EntityLinkage(LinkageType L) : Linkage(L) {}
- /// Returns the linkage type of this entity.
- ///
- /// \return The LinkageType indicating the entity's linkage.
LinkageType getLinkage() const { return Linkage; }
private:
- LinkageType Linkage = LinkageType::None;
+ LinkageType Linkage;
};
} // namespace clang::ssaf
diff --git a/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp b/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
index 0eb8ecd4fc97a..efd804de0af5f 100644
--- a/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
+++ b/clang/unittests/Analysis/Scalable/EntityLinkageTest.cpp
@@ -17,13 +17,11 @@ constexpr inline auto None = EntityLinkage::LinkageType::None;
constexpr inline auto Internal = EntityLinkage::LinkageType::Internal;
constexpr inline auto External = EntityLinkage::LinkageType::External;
-TEST(EntityLinkageTest, GetLinkageReturnsCorrectValue) {
- EntityLinkage Linkage;
+TEST(EntityLinkageTest, Constructor) {
EntityLinkage NoneLinkage(None);
EntityLinkage InternalLinkage(Internal);
EntityLinkage ExternalLinkage(External);
- EXPECT_EQ(Linkage.getLinkage(), None);
EXPECT_EQ(NoneLinkage.getLinkage(), None);
EXPECT_EQ(InternalLinkage.getLinkage(), Internal);
EXPECT_EQ(ExternalLinkage.getLinkage(), External);
More information about the cfe-commits
mailing list