[clang] [clang][ssaf] Add EntityLinkage data structure and update TUSummary (PR #181718)
Aviral Goel via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 16 10:50:25 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] 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
More information about the cfe-commits
mailing list