[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-12 Thread Nico Weber via cfe-commits


@@ -0,0 +1,18 @@
+add_distinct_clang_unittest(ClangScalableAnalysisFrameworkTests

nico wrote:

Why "Framework"? This tests clangAnalysisScalable, so the usual name would be 
AnalysisScalableTests, or with a Clang prefix if there's a naming conflict with 
another test (or I suppose for consistency with ClangAnalysisTests).

I see that you have a ClangScalableAnalysisTests below that depends on this 
here, but why the two targets instead of just one?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder `clang-armv7-global-isel` 
running on `linaro-clang-armv7-global-isel` while building `clang` at step 7 
"ninja check 1".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/39/builds/9052


Here is the relevant piece of the build log for the reference

```
Step 7 (ninja check 1) failure: stage 1 checked (failure)
 TEST 'LLVM :: CodeGen/X86/2009-03-23-MultiUseSched.ll' 
FAILED 
Exit Code: 2

Command Output (stdout):
--
# RUN: at line 3
/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/llc < 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/llvm/llvm/test/CodeGen/X86/2009-03-23-MultiUseSched.ll
 -mtriple=x86_64-linux -mcpu=corei7 -relocation-model=static | 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/FileCheck 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/llvm/llvm/test/CodeGen/X86/2009-03-23-MultiUseSched.ll
# executed command: 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/llc 
-mtriple=x86_64-linux -mcpu=corei7 -relocation-model=static
# .---command stderr
# | LLVM ERROR: out of memory
# | Allocation failed
# | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ 
and include the crash backtrace and instructions to reproduce the bug.
# | Stack dump:
# | 0.  Program arguments: 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/llc 
-mtriple=x86_64-linux -mcpu=corei7 -relocation-model=static
# | 1.  Running pass 'Function Pass Manager' on module ''.
# | 2.  Running pass 'X86 DAG->DAG Instruction Selection' on function '@foo'
# | #0 0x0ba9b6d0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
(/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/llc+0x39db6d0)
# | #1 0x0ba98b94 llvm::sys::RunSignalHandlers() 
(/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/llc+0x39d8b94)
# | #2 0x0ba9c690 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
# | #3 0xf0aad6f0 __default_rt_sa_restorer 
./signal/../sysdeps/unix/sysv/linux/arm/sigrestorer.S:80:0
# | #4 0xf0a9db06 ./csu/../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:47:0
# | #5 0xf0add292 __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
# | #6 0xf0aac840 gsignal ./signal/../sysdeps/posix/raise.c:27:6
# `-
# error: command failed with exit status: -6
# executed command: 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/FileCheck 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/llvm/llvm/test/CodeGen/X86/2009-03-23-MultiUseSched.ll
# .---command stderr
# | FileCheck error: '' is empty.
# | FileCheck command line:  
/home/tcwg-buildbot/worker/clang-armv7-global-isel/stage1/bin/FileCheck 
/home/tcwg-buildbot/worker/clang-armv7-global-isel/llvm/llvm/test/CodeGen/X86/2009-03-23-MultiUseSched.ll
# `-
# error: command failed with exit status: 2

--




```



https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread Jan Patrick Lehr via cfe-commits

jplehr wrote:

Has there been made any progress towards fixing this? Otherwise I'd like to 
revert this for now.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread Andy Kaylor via cfe-commits

andykaylor wrote:

@jkorous-apple This change is causing unit test build failures with shared 
libraries enabled. I think that may be what the buildbot failures are about.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread Kewen Meng via cfe-commits

Kewen12 wrote:

Hi, this PR failed clang test and breaks bots. Could you please fix or revert 
it? Thanks!
https://lab.llvm.org/buildbot/#/builders/10/builds/18836

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder `clang-ppc64le-rhel` 
running on `ppc64le-clang-rhel-test` while building `clang` at step 6 
"test-build-unified-tree-check-all".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/145/builds/11387


Here is the relevant piece of the build log for the reference

```
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
...
43.754 [2/1/83] Generating 
ASAN_INST_TEST_OBJECTS.gtest-all.cc.powerpc64le-inline.o
44.052 [0/2/84] Generating 
POWERPC64LELinuxDynamicConfig/Asan-powerpc64le-inline-Dynamic-Test
44.081 [0/1/85] Generating POWERPC64LELinuxConfig/Asan-powerpc64le-inline-Test
32.760 [4/3/1289] cd 
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/clang/bindings/python
 && /home/buildbots/llvm-external-buildbots/cmake-4.0.2/bin/cmake -E env 
CLANG_NO_DEFAULT_CONFIG=1 
CLANG_LIBRARY_PATH=/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib
 /home/buildbots/llvm-external-buildbots/workers/env/bin/python3.11 -m unittest 
discover
.
--
Ran 169 tests in 2.943s

OK
61.415 [3/2/1291] Linking CXX executable 
tools/clang/unittests/Analysis/Scalable/ClangScalableAnalysisFrameworkTests
FAILED: [code=1] 
tools/clang/unittests/Analysis/Scalable/ClangScalableAnalysisFrameworkTests 
: && /home/buildbots/llvm-external-buildbots/clang.20.1.8/bin/clang++ 
--gcc-toolchain=/gcc-toolchain/usr -fPIC -fno-semantic-interposition 
-fvisibility-inlines-hidden -Werror -Werror=date-time 
-Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter 
-Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic 
-Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion 
-Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported 
-fdiagnostics-color -ffunction-sections -fdata-sections -fno-common 
-Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG 
-Wl,--color-diagnostics   -Wl,--gc-sections  -Xlinker 
--dependency-file=tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/link.d
 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/ASTEntityMappingTest.cpp.o
 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/BuildNamespaceTest.cpp.o
 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/EntityNameTest.cpp.o
 -o tools/clang/unittests/Analysis/Scalable/ClangScalableAnalysisFrameworkTests 
 
-Wl,-rpath,/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib
  lib/libllvm_gtest_main.so.22.0git  lib/libllvm_gtest.so.22.0git  -lpthread  
lib/libclangAnalysisScalable.so.22.0git  lib/libclangTooling.so.22.0git  
lib/libclangSerialization.so.22.0git  lib/libclangASTMatchers.so.22.0git  
lib/libclangAST.so.22.0git  lib/libclangBasic.so.22.0git  
lib/libLLVMSupport.so.22.0git  
-Wl,-rpath-link,/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib
 && :
ld.lld: error: undefined symbol: clang::ASTUnit::~ASTUnit()
>>> referenced by ASTEntityMappingTest.cpp
>>>   
>>> tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/ASTEntityMappingTest.cpp.o:(clang::ssaf::(anonymous
>>>  namespace)::ASTEntityMappingTest_FunctionDecl_Test::TestBody())
>>> referenced by ASTEntityMappingTest.cpp
>>>   
>>> tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/ASTEntityMappingTest.cpp.o:(clang::ssaf::(anonymous
>>>  namespace)::ASTEntityMappingTest_VarDecl_Test::TestBody())
>>> referenced by ASTEntityMappingTest.cpp
>>>   
>>> tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/ASTEntityMappingTest.cpp.o:(clang::ssaf::(anonymous
>>>  namespace)::ASTEntityMappingTest_ParmVarDecl_Test::TestBody())
>>> referenced 13 more times
clang++: error: linker command failed with exit code 1 (use -v to see 
invocation)
ninja: build stopped: subcommand failed.

```



https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder 
`openmp-offload-amdgpu-runtime-2` running on `rocm-worker-hw-02` while building 
`clang` at step 7 "Add check check-clang".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/10/builds/18836


Here is the relevant piece of the build log for the reference

```
Step 7 (Add check check-clang) failure: test (failure)
...
/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.src/clang/unittests/Sema/HeuristicResolverTest.cpp:64:8:
 warning: variable ‘OutputNodeMatches’ set but not used 
[-Wunused-but-set-variable]
[304/313] Building CXX object 
tools/clang/unittests/Interpreter/CMakeFiles/ClangReplInterpreterTests.dir/CodeCompletionTest.cpp.o
[305/313] Building CXX object 
tools/clang/unittests/Interpreter/CMakeFiles/ClangReplInterpreterTests.dir/IncrementalProcessingTest.cpp.o
[306/313] Linking CXX executable tools/clang/unittests/Sema/SemaTests
[307/313] Linking CXX executable 
tools/clang/unittests/Interpreter/ClangReplInterpreterTests
[308/313] Building CXX object 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/EntityNameTest.cpp.o
[309/313] Building CXX object 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/BuildNamespaceTest.cpp.o
[310/313] Linking CXX executable tools/clang/unittests/AllClangUnitTests
[311/313] Building CXX object 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/ASTEntityMappingTest.cpp.o
[312/313] Linking CXX executable 
tools/clang/unittests/Analysis/Scalable/ClangScalableAnalysisFrameworkTests
FAILED: 
tools/clang/unittests/Analysis/Scalable/ClangScalableAnalysisFrameworkTests 
: && /usr/bin/c++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden 
-Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings 
-Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long 
-Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess 
-Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds 
-Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor 
-Wsuggest-override -Wno-comment -Wno-misleading-indentation 
-Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections 
-fdata-sections -fno-common -Woverloaded-virtual -O3 -DNDEBUG -Wl,--gc-sections 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/ASTEntityMappingTest.cpp.o
 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/BuildNamespaceTest.cpp.o
 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/EntityNameTest.cpp.o
 -o tools/clang/unittests/Analysis/Scalable/ClangScalableAnalysisFrameworkTests 
 
-Wl,-rpath,/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/lib
  lib/libllvm_gtest_main.so.22.0git  lib/libllvm_gtest.so.22.0git  
lib/libclangAnalysisScalable.so.22.0git  lib/libclangTooling.so.22.0git  
lib/libclangSerialization.so.22.0git  lib/libclangASTMatchers.so.22.0git  
lib/libclangAST.so.22.0git  lib/libclangBasic.so.22.0git  
lib/libLLVMSupport.so.22.0git  
-Wl,-rpath-link,/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/lib
 && :
/usr/bin/ld: 
tools/clang/unittests/Analysis/Scalable/CMakeFiles/ClangScalableAnalysisFrameworkTests.dir/ASTEntityMappingTest.cpp.o:
 undefined reference to symbol '_ZN5clang7ASTUnitD1Ev'
/usr/bin/ld: 
/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/lib/libclangFrontend.so.22.0git:
 error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

```



https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple closed 
https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+

ymand wrote:

waiting SGTM. thx

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand approved this pull request.


https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-10 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.

ymand wrote:

New comment looks good.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-09 Thread Jan Korous via cfe-commits


@@ -0,0 +1,56 @@
+//===- EntityName.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_ENTITYNAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_ENTITYNAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang::ssaf {
+/// Uniquely identifies an entity in a program.

jkorous-apple wrote:

There is a fair amount of complexity in relating entities indeed.
At this point we are just creating foundations that we will use in the future 
(hopefully soon) to implement entity linking and resolution. We know that we 
will need more data than just `EntityName` for that. We are also aware that 
until we actually implement it, this is only our best guess of what will be 
necessary. If we later find out the `EntityName` is missing something, we will 
enhance it. The right place to document, implement and test all that logic will 
be in the patches that introduce entity linker and the APIs for lookup in 
analysis result data.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-09 Thread Jan Korous via cfe-commits


@@ -0,0 +1,357 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  if (auto Result = Matches[0].getNodeAs("decl"))
+return dyn_cast(Result->getCanonicalDecl());
+  return nullptr;
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_EQ(FD->param_size(), 1u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  const CXXConstructorDecl * ImplCtor = nullptr;
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  ImplCtor = Ctor;
+  break;
+}
+  }
+
+  auto EntityName = getLocalEntityNameForDecl(ImplCtor);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_EQ(Matches.size(), 1ul);
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  ASSERT_NE(Callee, nullptr);
+  ASSERT_NE(Callee->getBuiltinID(), 0u /* not a built-in */);
+
+  auto EntityName = getLocalEntityNameForDecl(Callee);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto E

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-09 Thread Gábor Horváth via cfe-commits


@@ -0,0 +1,56 @@
+//===- EntityName.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_ENTITYNAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_ENTITYNAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang::ssaf {
+/// Uniquely identifies an entity in a program.

Xazax-hun wrote:

I have some concerns about how certain entities will be uniquely identified. 
There are lots of edge cases as the result of the compilation model of C and 
C++. Specifically, the same entity might be forward declared in multiple 
compilation units (in entirely different header files). Do we consider those to 
be the same entity or not? Or do we only care about complete types?  We do not 
need to answer all of these questions but I think we should start planning 
around these scenarios early and document the behavior via some test. 

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-09 Thread Gábor Horváth via cfe-commits

https://github.com/Xazax-hun edited 
https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-09 Thread Gábor Horváth via cfe-commits

https://github.com/Xazax-hun approved this pull request.

Overall looks good to me, I have one concern that I shared inline but it should 
not be blocking. 

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-09 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,357 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  if (auto Result = Matches[0].getNodeAs("decl"))
+return dyn_cast(Result->getCanonicalDecl());
+  return nullptr;
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_EQ(FD->param_size(), 1u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  const CXXConstructorDecl * ImplCtor = nullptr;
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  ImplCtor = Ctor;
+  break;
+}
+  }
+
+  auto EntityName = getLocalEntityNameForDecl(ImplCtor);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_EQ(Matches.size(), 1ul);
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  ASSERT_NE(Callee, nullptr);
+  ASSERT_NE(Callee->getBuiltinID(), 0u /* not a built-in */);
+
+  auto EntityName = getLocalEntityNameForDecl(Callee);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto E

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-09 Thread Balázs Benics via cfe-commits

https://github.com/steakhal approved this pull request.

It looks good enough for me.
I'd suggest everyone to look at the remaining comments and act if it's still 
relevant, or resolve the comment otherwise.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-08 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/23] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-08 Thread Jan Korous via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.

jkorous-apple wrote:

That's an interesting question.

I've tweaked the doc comment a bit but I suspect I am not fully answering your 
question.

I can imagine that waiting with adding this overload until I can show its use 
might be better. WDYT?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-08 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/20] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-08 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,357 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  if (auto Result = Matches[0].getNodeAs("decl"))
+return dyn_cast(Result->getCanonicalDecl());
+  return nullptr;
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_EQ(FD->param_size(), 1u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  const CXXConstructorDecl * ImplCtor = nullptr;
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  ImplCtor = Ctor;
+  break;
+}
+  }
+
+  auto EntityName = getLocalEntityNameForDecl(ImplCtor);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_EQ(Matches.size(), 1ul);
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  ASSERT_NE(Callee, nullptr);
+  ASSERT_NE(Callee->getBuiltinID(), 0u /* not a built-in */);
+
+  auto EntityName = getLocalEntityNameForDecl(Callee);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto E

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-08 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }

steakhal wrote:

I just re-read this hunk and I'd still stand by my previous comment.
I don't particularly see mutable variables and control flow helpful for 
debugging.

What is also missing for me is that we can't distinguish later the failures from
 - `getLocalEntityNameForDecl` taking a non null ImplCtor and returning null 
opt; or
 - `getLocalEntityNameForDecl` taking a nullptr and then returning a null opt.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-08 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,86 @@
+//===- BuildNamespace.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_BUILDNAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_BUILDNAMESPACE_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang::ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+llvm::StringRef toString(BuildNamespaceKind BNK);

steakhal wrote:

It is in a header. I think it needs to be llvm qualified.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

jkorous-apple wrote:

Thank you all for great feedback!
I have unfortunately been distracted with other tasks this week but I am 
working my way though all the comments.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple edited 
https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {
+  std::string USR;
+  llvm::SmallString<16> Suffix;
+  NestedBuildNamespace Namespace;

jkorous-apple wrote:

My plan is to actually use 64-bit IDs to represent entities in most contexts.

A follow-up PR introduces that:
https://github.com/jkorous-apple/llvm-project/pull/1

I imagine `EntityName` will mostly be used for linking and for mapping entities 
back to the AST which we need for source code rewriting tools.

The compilation unit IDs and link unit IDs that the namespaces use as names 
will be supplied to the framework by external tools. We imagine the 
implementation will need to be space-efficient and while this API doesn't 
impose such restriction, it is unlikely that we could use long strings.

With the current API design (with `EntityIdTable`), during summary extraction, 
we would still have an instance of `EntityName` for each entity contributing a 
fact or being referred to by a summary. I plan to factor out the common 
namespace prefix with compilation unit id and have individual entity names 
unqualified.

For summary analysis part, when we might need to represent all entities of a 
program in memory at once, having even a single instance of EntityName for each 
entity in memory might be impossible for large programs. If that turns out to 
be true we might need a different representation than `EntityName`, `EntityId` 
and `EntityIdTable`.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/19] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/18] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_FALSE(Matches.empty());
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  if (Callee && Callee->getBuiltinID()) {
+auto EntityName = getLocalEntityNameForDecl(Callee);
+EXPECT_FALSE(EntityName.has_value());
+  }
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto EntityName = getLocalEntityNameForFunctionReturn(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnBuiltin) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test(

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/17] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/16] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple edited 
https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_FALSE(Matches.empty());
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  if (Callee && Callee->getBuiltinID()) {
+auto EntityName = getLocalEntityNameForDecl(Callee);
+EXPECT_FALSE(EntityName.has_value());
+  }
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto EntityName = getLocalEntityNameForFunctionReturn(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnBuiltin) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test(

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_FALSE(Matches.empty());
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  if (Callee && Callee->getBuiltinID()) {
+auto EntityName = getLocalEntityNameForDecl(Callee);
+EXPECT_FALSE(EntityName.has_value());
+  }
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto EntityName = getLocalEntityNameForFunctionReturn(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnBuiltin) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test(

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-05 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/15] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(

jkorous-apple wrote:

Thanks for the tip-I was not aware of that. My preference would be to keep the 
snippets short-enough to not need clang-format. In your experience, is it worth 
the extra bit of effort?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_FALSE(Matches.empty());
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  if (Callee && Callee->getBuiltinID()) {

jkorous-apple wrote:

Good catch. Thanks!

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/14] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/13] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple edited 
https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/12] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }

jkorous-apple wrote:

I've separated the search for the implicit ctor from the test assertion. I 
prefer to keep the for loop though because while non-elegant it is simple to 
understand and debug.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/11] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");

jkorous-apple wrote:

I agree that the code seems more verbose than necessary but I suggest waiting 
until we have more patches to get better feel for what shared test utilities we 
want to build.

I imagine we could later somehow create a test fixture to store the 
std::unique_ptr returned by buildASTFromCode.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);

jkorous-apple wrote:

I have a slight preference for explicitly spelling out the intent rather than 
relying on implicit conversion.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 01/10] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");

jkorous-apple wrote:

That is difficult for reasons like struct definition introducing additional 
implicit declaration, etc.
I've changed the helper to return the canonical declaration.
Do you think that works?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 1/9] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 1/8] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 1/7] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-04 Thread Gábor Horváth via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.
+class BuildNamespace {
+  BuildNamespaceKind Kind;
+  std::string Name;
+public:
+  BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
+: Kind(Kind), Name(Name.str()) {}
+
+  static BuildNamespace makeTU(llvm::StringRef CompilationId);
+
+  bool operator==(const BuildNamespace& Other) const;
+  bool operator!=(const BuildNamespace& Other) const;
+  bool operator<(const BuildNamespace& Other) const;
+
+  friend class SerializationFormat;
+};
+
+/// Represents a sequence of steps in the build process.

Xazax-hun wrote:

I do not have a strong preference or reason other than I feel like this would 
make the implementation a bit more concise and I usually prefer the more 
concise form until there is a need to split functionality out.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-03 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple updated 
https://github.com/llvm/llvm-project/pull/169131

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH 1/6] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-03 Thread Jan Korous via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {
+  std::string USR;
+  llvm::SmallString<16> Suffix;
+  NestedBuildNamespace Namespace;
+
+public:
+  EntityName(llvm::StringRef USR, llvm::StringRef Suffix,
+ NestedBuildNamespace Namespace);
+
+  bool operator==(const EntityName& Other) const;
+  bool operator!=(const EntityName& Other) const;
+  bool operator<(const EntityName& Other) const;
+
+  EntityName makeQualified(NestedBuildNamespace Namespace);

jkorous-apple wrote:

You are right! It's missing the `const`. I'm adding the doc comments too.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-03 Thread Jan Korous via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {
+  std::string USR;
+  llvm::SmallString<16> Suffix;

jkorous-apple wrote:

In my view having more structure in the data makes it more simpler in terms of 
understanding the content, for example during debugging.

It is pretty likely that in the future we will have to either optimize this 
scheme or enhance USRs so we don't need suffixes which makes me not want to 
spend a ton of time polishing this during bring-up.

What do you see as the strongest argument for keeping the strings merged?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-12-03 Thread Jan Korous via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.
+class BuildNamespace {
+  BuildNamespaceKind Kind;
+  std::string Name;
+public:
+  BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
+: Kind(Kind), Name(Name.str()) {}
+
+  static BuildNamespace makeTU(llvm::StringRef CompilationId);
+
+  bool operator==(const BuildNamespace& Other) const;
+  bool operator!=(const BuildNamespace& Other) const;
+  bool operator<(const BuildNamespace& Other) const;
+
+  friend class SerializationFormat;
+};
+
+/// Represents a sequence of steps in the build process.

jkorous-apple wrote:

Let me preface this by saying that the namespace design will possibly evolve 
when we actually implement entity linking. To some degree this is just an 
educated guess.

We could just use `std::vector` instead of introducing another 
class but I expect that we will have operations on that type and having this 
class will allow the interfaces to enforce type correctness and to be 
self-descriptive. Alternatively, we could have `BuildNamespace` implemented as 
`std::vector>` and sink the 
per-element logic to its implementation.

So, yes, I can imagine there's only a single type but can you please elaborate 
on why would you prefer that?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {

ymand wrote:

nit: Consider `EntityID` -- its shorter and (IMO) more intuitive. I think of 
"name" more for circumstances where the identifier is readable. But, it's a 
matter of taste. 

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.
+class BuildNamespace {
+  BuildNamespaceKind Kind;
+  std::string Name;
+public:
+  BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
+: Kind(Kind), Name(Name.str()) {}
+
+  static BuildNamespace makeTU(llvm::StringRef CompilationId);
+
+  bool operator==(const BuildNamespace& Other) const;
+  bool operator!=(const BuildNamespace& Other) const;
+  bool operator<(const BuildNamespace& Other) const;
+
+  friend class SerializationFormat;
+};
+
+/// Represents a sequence of steps in the build process.
+class NestedBuildNamespace {
+  friend class SerializationFormat;
+
+  std::vector Namespaces;
+
+public:
+  NestedBuildNamespace() = default;
+
+  explicit NestedBuildNamespace(const std::vector& Namespaces)
+: Namespaces(Namespaces) {}
+
+  explicit NestedBuildNamespace(const BuildNamespace& N) {
+Namespaces.push_back(N);
+  }
+
+  static NestedBuildNamespace makeTU(llvm::StringRef CompilationId);

ymand wrote:

Please comment.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.

ymand wrote:

I think it would help to spell out in more detail what you mean/why this 
specialization is necessary. It's not really the type that's being identified, 
or you could just separately identify the type. It's specifically the return 
entity of this function.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {
+  std::string USR;

ymand wrote:

I think it would be helpful to explain the roles of these fields. Perhaps copy 
some of the information from the PR description. To the casual reader "USR" 
won't have much meaning and since the type is string that won't inform them 
either. Additionally, the need for the suffix won't be obvious. Similarly, the 
role of `Namespace` in distinguishing between otherwise identical entities.

Alternatively, provide a detailed explanation on the class comments or the 
constructor.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+

ymand wrote:

For both of these lookup functions -- I expect these to be used heavily in 
analysis, so it would be beneficial if they were shorter names. Currently, the 
names encode a lot of the (existing) type information. Is that 
necessary/helpful? Could you instead go with a simpler scheme like `getEntity` 
and `getReturnEntity`?

Separately: constructing these is typically expensive, so we use a cache. 
Consider including a cache object in this library as well. I think that will be 
the correct choice for most use cases.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {
+  std::string USR;
+  llvm::SmallString<16> Suffix;
+  NestedBuildNamespace Namespace;

ymand wrote:

I'm afraid of the size implications of including this. USRs are already large, 
but including an arbitrarily large vector as well, in each ID, threatens to 
make this unusable for large scale application.

Does the entity name need the full vector, or could something like a unique 
64-bit ID suffice? 

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand requested changes to this pull request.

I'm really excited to see these patches start to land! I reviewed the header 
files, focusing on the API. I'll try to get back to implementation and tests 
soon, but wanted to get these out in the meantime.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.

ymand wrote:

Could you expand this comment? It's not immediately obvious how a step in the 
build process relates to the notion of "namespace". Alternatively (or maybe 
additionally), consider adding some background explanation to the beginning of 
the file.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand edited https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,18 @@
+add_distinct_clang_unittest(ClangScalableAnalysisFrameworkTests
+  BuildNamespaceTest.cpp
+  EntityNameTest.cpp
+  ASTEntityMappingTest.cpp
+
+  CLANG_LIBS
+  clangAnalysisScalable
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangSerialization
+  clangTooling

steakhal wrote:

Could you please sort these lists?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_FALSE(Matches.empty());
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  if (Callee && Callee->getBuiltinID()) {
+auto EntityName = getLocalEntityNameForDecl(Callee);
+EXPECT_FALSE(EntityName.has_value());
+  }
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto EntityName = getLocalEntityNameForFunctionReturn(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnBuiltin) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test(

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");

steakhal wrote:

Shall we express the expectation that there should be no more than a single 
match?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {

steakhal wrote:

+1 In many other cases as well.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");

steakhal wrote:

This triplet kinda repeats across the tests.
I wonder if we could hoist these in a clever way.
For example, wrap these and `const auto *FD = get("foo", "void 
foo(int x) {}")`.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,85 @@
+//===- ASTMapping.cpp - AST to SSAF Entity mapping --*- 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 implements utilities for mapping AST declarations to SSAF 
entities.
+//
+//===--===//
+
+#include "clang/Analysis/Scalable/ASTEntityMapping.h"
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/SmallString.h"
+
+namespace clang {
+namespace ssaf {
+
+std::optional getLocalEntityNameForDecl(const Decl* D) {
+  if (!D)
+return std::nullopt;
+
+  if (D->isImplicit())
+return std::nullopt;
+
+  if (isa(D) && cast(D)->getBuiltinID())
+return std::nullopt;
+
+  if (!isa(D) && !isa(D) && !isa(D) &&
+  !isa(D) && !isa(D))

steakhal wrote:

```suggestion
  if (!isa(D))
```

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }

steakhal wrote:

I dislike the early return. It makes me think about the control-flow and the 
loop.
I wonder if using `llvm::find_singleton` would make this more declarative?
Having a predicate for selecting the desired constructor and then apply the 
test.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);

steakhal wrote:

```suggestion
  ASSERT_EQ(FD->param_size(), 1u);
```
Why not pin this to the exact value?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_FALSE(Matches.empty());

steakhal wrote:

We probably should express that we expect exactly 1 match.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,72 @@
+//===- BuildNamespace.cpp ---*- 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
+//
+//===--===//
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+namespace ssaf {
+
+std::string toString(BuildNamespaceKind BNK) {
+  switch(BNK) {
+case BuildNamespaceKind::CompilationUnit: return "compilation_unit";
+case BuildNamespaceKind::LinkUnit: return "link_unit";
+  }
+  llvm_unreachable("Unknown BuildNamespaceKind");
+}
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str) 
{
+  if (Str == "compilation_unit")
+return BuildNamespaceKind::CompilationUnit;
+  if (Str == "link_unit")
+return BuildNamespaceKind::LinkUnit;
+  return std::nullopt;
+}
+
+BuildNamespace BuildNamespace::makeTU(llvm::StringRef CompilationId) {
+  return BuildNamespace{BuildNamespaceKind::CompilationUnit, 
CompilationId.str()};
+}
+
+bool BuildNamespace::operator==(const BuildNamespace& Other) const {
+  return Kind == Other.Kind && Name == Other.Name;
+}
+
+bool BuildNamespace::operator!=(const BuildNamespace& Other) const {
+  return !(*this == Other);
+}
+
+bool BuildNamespace::operator<(const BuildNamespace& Other) const {
+  if (Kind != Other.Kind)
+return Kind < Other.Kind;
+  return Name < Other.Name;

steakhal wrote:

Have you thought of using `std::tie`? I find this a more natural way to express 
the ordering.

```suggestion
  return std::tie(Kind, Name) < std::tie(Other.Kind, Other.Name);
```

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,85 @@
+//===- ASTMapping.cpp - AST to SSAF Entity mapping --*- 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 implements utilities for mapping AST declarations to SSAF 
entities.
+//
+//===--===//
+
+#include "clang/Analysis/Scalable/ASTEntityMapping.h"
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/SmallString.h"
+
+namespace clang {
+namespace ssaf {
+
+std::optional getLocalEntityNameForDecl(const Decl* D) {
+  if (!D)
+return std::nullopt;
+
+  if (D->isImplicit())
+return std::nullopt;
+
+  if (isa(D) && cast(D)->getBuiltinID())
+return std::nullopt;
+
+  if (!isa(D) && !isa(D) && !isa(D) &&
+  !isa(D) && !isa(D))
+return std::nullopt;
+
+  llvm::SmallString<16> Suffix;
+  const Decl *USRDecl = D;
+
+  // For parameters, use the parent function's USR with parameter index as 
suffix
+  if (const auto * PVD = dyn_cast(D)) {
+const auto *FD = 
dyn_cast_or_null(PVD->getParentFunctionOrMethod());
+if (!FD)
+  return std::nullopt;
+USRDecl = FD;
+
+const auto ParamIdx = PVD->getFunctionScopeIndex();
+llvm::raw_svector_ostream OS(Suffix);
+// Parameter uses function's USR with 1-based index as suffix
+OS << (ParamIdx + 1);
+  }
+
+  llvm::SmallString<128> USRBuf;
+  if (clang::index::generateUSRForDecl(USRDecl, USRBuf)) {
+return std::nullopt;
+  }
+
+  if (USRBuf.empty())
+return std::nullopt;
+
+  return EntityName(USRBuf.str(), Suffix, {});
+}
+
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD) {
+  if (!FD)
+return std::nullopt;
+
+  if (FD->isImplicit())
+return std::nullopt;
+
+  if (FD->getBuiltinID())
+return std::nullopt;
+
+  llvm::SmallString<128> USRBuf;
+  if (clang::index::generateUSRForDecl(FD, USRBuf)) {
+return std::nullopt;
+  }
+
+  if (USRBuf.empty())
+return std::nullopt;
+
+  return EntityName(USRBuf.str(), "0", {});

steakhal wrote:

```suggestion
  return EntityName(USRBuf.str(), /*Suffix=*/"0", /*Namespace=*/{});
```

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {
+  std::string USR;
+  llvm::SmallString<16> Suffix;
+  NestedBuildNamespace Namespace;
+
+public:
+  EntityName(llvm::StringRef USR, llvm::StringRef Suffix,
+ NestedBuildNamespace Namespace);
+
+  bool operator==(const EntityName& Other) const;
+  bool operator!=(const EntityName& Other) const;
+  bool operator<(const EntityName& Other) const;
+
+  EntityName makeQualified(NestedBuildNamespace Namespace);

steakhal wrote:

Oh, so this isn't a factory function. This is not static. I was surprised about 
this.
It might be useful to have 1-liner docs for these APIs like this one or in the 
other classes for the static factory functions about when to use one.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,44 @@
+//===- EntityName.cpp ---*- 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
+//
+//===--===//
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+
+namespace clang {
+namespace ssaf {
+
+EntityName::EntityName(llvm::StringRef USR, llvm::StringRef Suffix,
+   NestedBuildNamespace Namespace)
+  : USR(USR.str()), Suffix(Suffix), Namespace(std::move(Namespace)) {}
+
+bool EntityName::operator==(const EntityName& Other) const {
+  return USR == Other.USR &&
+ Suffix == Other.Suffix &&
+ Namespace == Other.Namespace;
+}

steakhal wrote:

What if we had a private `asTuple` member function and just call `asTuple() == 
Other.asTuple()` here?
Similarly in the `operator<`, calling `asTuple() < Other.asTuple()`?

```c++
auto asTuple() const { return std::tie(USR, Suffix, Namespace); }
```
Or something similar.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,47 @@
+//===- EntityName.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_ENTITY_NAME_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ENTITY_NAME_H
+
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Uniquely identifies an entity in a program.
+///
+/// EntityName provides a globally unique identifier for program entities that 
remains
+/// stable across compilation boundaries. This enables whole-program analysis 
to track
+/// and relate entities across separately compiled translation units.
+class EntityName {
+  std::string USR;
+  llvm::SmallString<16> Suffix;

steakhal wrote:

What's the benefit of having two different string types close together?
Unless there is a good reason, for simplicity, I'd just stick with one.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, VarDecl) {
+  auto AST = tooling::buildASTFromCode("int x = 42;");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *VD = findDecl(Ctx, "x");
+  ASSERT_NE(VD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(VD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ParmVarDecl) {
+  auto AST = tooling::buildASTFromCode("void foo(int x) {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+  ASSERT_GT(FD->param_size(), 0u);
+
+  const auto *PVD = FD->getParamDecl(0);
+  ASSERT_NE(PVD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(PVD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, RecordDecl) {
+  auto AST = tooling::buildASTFromCode("struct S {};");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(RD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FieldDecl) {
+  auto AST = tooling::buildASTFromCode("struct S { int field; };");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "field");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, NullDecl) {
+  auto EntityName = getLocalEntityNameForDecl(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, ImplicitDecl) {
+  auto AST = tooling::buildASTFromCode(R"(
+struct S {
+  S() = default;
+};
+  )", "test.cpp", std::make_shared());
+  auto &Ctx = AST->getASTContext();
+
+  const auto *RD = findDecl(Ctx, "S");
+  ASSERT_NE(RD, nullptr);
+
+  // Find the implicitly-declared copy constructor
+  for (const auto *Ctor : RD->ctors()) {
+if (Ctor->isCopyConstructor() && Ctor->isImplicit()) {
+  auto EntityName = getLocalEntityNameForDecl(Ctor);
+  EXPECT_FALSE(EntityName.has_value());
+  return;
+}
+  }
+}
+
+TEST(ASTEntityMappingTest, BuiltinFunction) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test() {
+  __builtin_memcpy(0, 0, 0);
+}
+  )");
+  auto &Ctx = AST->getASTContext();
+
+  // Find the builtin call
+  auto Matcher = callExpr().bind("call");
+  auto Matches = match(Matcher, Ctx);
+  ASSERT_FALSE(Matches.empty());
+
+  const auto *CE = Matches[0].getNodeAs("call");
+  ASSERT_NE(CE, nullptr);
+
+  const auto *Callee = CE->getDirectCallee();
+  if (Callee && Callee->getBuiltinID()) {
+auto EntityName = getLocalEntityNameForDecl(Callee);
+EXPECT_FALSE(EntityName.has_value());
+  }
+}
+
+TEST(ASTEntityMappingTest, UnsupportedDecl) {
+  auto AST = tooling::buildASTFromCode("namespace N {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *ND = findDecl(Ctx, "N");
+  ASSERT_NE(ND, nullptr);
+
+  auto EntityName = getLocalEntityNameForDecl(ND);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturn) {
+  auto AST = tooling::buildASTFromCode("int foo() { return 42; }");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);
+
+  auto EntityName = getLocalEntityNameForFunctionReturn(FD);
+  EXPECT_TRUE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnNull) {
+  auto EntityName = getLocalEntityNameForFunctionReturn(nullptr);
+  EXPECT_FALSE(EntityName.has_value());
+}
+
+TEST(ASTEntityMappingTest, FunctionReturnBuiltin) {
+  auto AST = tooling::buildASTFromCode(R"(
+void test(

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields

steakhal wrote:

I wonder what support `BlockDecls` or `ObjCMethodDecls` going to get - given 
that they are like callables but not derived from FunctionDecls.

Shall we explicitly state that they are not supported? Or do you have plans to 
ever support them?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,343 @@
+//===- unittests/Analysis/Scalable/ASTEntityMappingTest.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/ASTEntityMapping.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ssaf {
+namespace {
+
+// Helper function to find a declaration by name
+template 
+const DeclType *findDecl(ASTContext &Ctx, StringRef Name) {
+  auto Matcher = namedDecl(hasName(Name)).bind("decl");
+  auto Matches = match(Matcher, Ctx);
+  if (Matches.empty())
+return nullptr;
+  return Matches[0].getNodeAs("decl");
+}
+
+TEST(ASTEntityMappingTest, FunctionDecl) {
+  auto AST = tooling::buildASTFromCode("void foo() {}");
+  auto &Ctx = AST->getASTContext();
+
+  const auto *FD = findDecl(Ctx, "foo");
+  ASSERT_NE(FD, nullptr);

steakhal wrote:

```suggestion
  ASSERT_TRUE(FD);
```
I find this a more natural way to express the validity of a pointer.
Probably because people tend to do `if (FD)` to express this.
This applies to other pointer checks.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H

steakhal wrote:

I think in LLVM, the header guards should reflect the relative path.
https://llvm.org/docs/CodingStandards.html#header-guard
This applies to the other header guards as well.

```suggestion
#ifndef LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_BUILDNAMESPACE_H
#define LLVM_CLANG_ANALYSIS_SCALABLE_MODEL_BUILDNAMESPACE_H
```

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Balázs Benics via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.
+class BuildNamespace {
+  BuildNamespaceKind Kind;
+  std::string Name;
+public:
+  BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
+: Kind(Kind), Name(Name.str()) {}
+
+  static BuildNamespace makeTU(llvm::StringRef CompilationId);
+
+  bool operator==(const BuildNamespace& Other) const;
+  bool operator!=(const BuildNamespace& Other) const;
+  bool operator<(const BuildNamespace& Other) const;
+
+  friend class SerializationFormat;
+};
+
+/// Represents a sequence of steps in the build process.
+class NestedBuildNamespace {
+  friend class SerializationFormat;
+
+  std::vector Namespaces;
+
+public:
+  NestedBuildNamespace() = default;
+
+  explicit NestedBuildNamespace(const std::vector& Namespaces)
+: Namespaces(Namespaces) {}
+
+  explicit NestedBuildNamespace(const BuildNamespace& N) {
+Namespaces.push_back(N);
+  }
+
+  static NestedBuildNamespace makeTU(llvm::StringRef CompilationId);
+
+  NestedBuildNamespace makeQualified(NestedBuildNamespace Namespace) {
+auto Copy = *this;
+for (const auto& N : Namespace.Namespaces)
+  Copy.Namespaces.push_back(N);

steakhal wrote:

Could we use `llvm::append_range` here?
We know ahead of time how many elements we add. Could we reserve?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Gábor Horváth via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);

Xazax-hun wrote:

Nit: could this return a `StringRef`?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Gábor Horváth via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {

Xazax-hun wrote:

Nit: I think we can use nested namespaces now, like `namespace clang::ssaf`.

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Gábor Horváth via cfe-commits


@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.
+class BuildNamespace {
+  BuildNamespaceKind Kind;
+  std::string Name;
+public:
+  BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
+: Kind(Kind), Name(Name.str()) {}
+
+  static BuildNamespace makeTU(llvm::StringRef CompilationId);
+
+  bool operator==(const BuildNamespace& Other) const;
+  bool operator!=(const BuildNamespace& Other) const;
+  bool operator<(const BuildNamespace& Other) const;
+
+  friend class SerializationFormat;
+};
+
+/// Represents a sequence of steps in the build process.

Xazax-hun wrote:

Is it important to preserve the information what entities belong to the same 
step or could a `NestedBuildNamespace` be not a different type just the result 
of merging some `BuildNamespace`s?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-28 Thread Gábor Horváth via cfe-commits


@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);

Xazax-hun wrote:

What does the "Local" refer to in the name?

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-21 Thread via cfe-commits

github-actions[bot] wrote:


# :penguin: Linux x64 Test Results

* 111392 tests passed
* 4438 tests skipped

https://github.com/llvm/llvm-project/pull/169131
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-21 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff origin/main HEAD --extensions h,cpp -- 
clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
clang/include/clang/Analysis/Scalable/Model/EntityName.h 
clang/lib/Analysis/Scalable/ASTEntityMapping.cpp 
clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp 
clang/lib/Analysis/Scalable/Model/EntityName.cpp 
clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp 
clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp 
clang/unittests/Analysis/Scalable/EntityNameTest.cpp --diff_from_common_commit
``

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
index a137e8b74..435b3afdb 100644
--- a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
 #define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
 
-#include "clang/Analysis/Scalable/Model/EntityName.h"
 #include "clang/AST/Decl.h"
+#include "clang/Analysis/Scalable/Model/EntityName.h"
 #include "llvm/ADT/StringRef.h"
 #include 
 
@@ -30,15 +30,17 @@ namespace ssaf {
 ///
 /// \param D The declaration to map. Must not be null.
 ///
-/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
-std::optional getLocalEntityNameForDecl(const Decl* D);
+/// \return An EntityName if the declaration can be mapped, std::nullopt
+/// otherwise.
+std::optional getLocalEntityNameForDecl(const Decl *D);
 
 /// Maps a function return type to an EntityName.
 ///
 /// \param FD The function declaration. Must not be null.
 ///
 /// \return An EntityName for the function's return type.
-std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+std::optional
+getLocalEntityNameForFunctionReturn(const FunctionDecl *FD);
 
 } // namespace ssaf
 } // namespace clang
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
index c4bf7146e..b77fa0501 100644
--- a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -17,10 +17,7 @@
 namespace clang {
 namespace ssaf {
 
-enum class BuildNamespaceKind : unsigned short {
-  CompilationUnit,
-  LinkUnit
-};
+enum class BuildNamespaceKind : unsigned short { CompilationUnit, LinkUnit };
 
 std::string toString(BuildNamespaceKind BNK);
 
@@ -30,15 +27,16 @@ std::optional 
parseBuildNamespaceKind(llvm::StringRef Str);
 class BuildNamespace {
   BuildNamespaceKind Kind;
   std::string Name;
+
 public:
   BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
-: Kind(Kind), Name(Name.str()) {}
+  : Kind(Kind), Name(Name.str()) {}
 
   static BuildNamespace makeTU(llvm::StringRef CompilationId);
 
-  bool operator==(const BuildNamespace& Other) const;
-  bool operator!=(const BuildNamespace& Other) const;
-  bool operator<(const BuildNamespace& Other) const;
+  bool operator==(const BuildNamespace &Other) const;
+  bool operator!=(const BuildNamespace &Other) const;
+  bool operator<(const BuildNamespace &Other) const;
 
   friend class SerializationFormat;
 };
@@ -52,10 +50,10 @@ class NestedBuildNamespace {
 public:
   NestedBuildNamespace() = default;
 
-  explicit NestedBuildNamespace(const std::vector& Namespaces)
-: Namespaces(Namespaces) {}
+  explicit NestedBuildNamespace(const std::vector &Namespaces)
+  : Namespaces(Namespaces) {}
 
-  explicit NestedBuildNamespace(const BuildNamespace& N) {
+  explicit NestedBuildNamespace(const BuildNamespace &N) {
 Namespaces.push_back(N);
   }
 
@@ -63,16 +61,16 @@ public:
 
   NestedBuildNamespace makeQualified(NestedBuildNamespace Namespace) {
 auto Copy = *this;
-for (const auto& N : Namespace.Namespaces)
+for (const auto &N : Namespace.Namespaces)
   Copy.Namespaces.push_back(N);
 return Copy;
   }
 
   bool empty() const;
 
-  bool operator==(const NestedBuildNamespace& Other) const;
-  bool operator!=(const NestedBuildNamespace& Other) const;
-  bool operator<(const NestedBuildNamespace& Other) const;
+  bool operator==(const NestedBuildNamespace &Other) const;
+  bool operator!=(const NestedBuildNamespace &Other) const;
+  bool operator<(const NestedBuildNamespace &Other) const;
 
   friend class JSONWriter;
   friend class LinkUnitResolution;
d

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-21 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-analysis

Author: Jan Korous (jkorous-apple)


Changes

Add core abstractions for identifying program entities across compilation and 
link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying 
mechanism, with extensions for sub-entities (parameters, return values) via 
suffixes. The abstraction allows whole-program analysis by providing stable 
identifiers that persist across separately compiled translation units.

---

Patch is 30.31 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/169131.diff


13 Files Affected:

- (added) clang/include/clang/Analysis/Scalable/ASTEntityMapping.h (+46) 
- (added) clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h (+84) 
- (added) clang/include/clang/Analysis/Scalable/Model/EntityName.h (+47) 
- (modified) clang/lib/Analysis/CMakeLists.txt (+1) 
- (added) clang/lib/Analysis/Scalable/ASTEntityMapping.cpp (+85) 
- (added) clang/lib/Analysis/Scalable/CMakeLists.txt (+19) 
- (added) clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp (+72) 
- (added) clang/lib/Analysis/Scalable/Model/EntityName.cpp (+44) 
- (modified) clang/unittests/Analysis/CMakeLists.txt (+1) 
- (added) clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp (+343) 
- (added) clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp (+99) 
- (added) clang/unittests/Analysis/Scalable/CMakeLists.txt (+18) 
- (added) clang/unittests/Analysis/Scalable/EntityNameTest.cpp (+62) 


``diff
diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.
+class BuildNamespace {
+  BuildNamespaceKind Kind;
+  std::string Name;
+public:
+  BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
+: Kind(K

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-21 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Jan Korous (jkorous-apple)


Changes

Add core abstractions for identifying program entities across compilation and 
link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying 
mechanism, with extensions for sub-entities (parameters, return values) via 
suffixes. The abstraction allows whole-program analysis by providing stable 
identifiers that persist across separately compiled translation units.

---

Patch is 30.31 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/169131.diff


13 Files Affected:

- (added) clang/include/clang/Analysis/Scalable/ASTEntityMapping.h (+46) 
- (added) clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h (+84) 
- (added) clang/include/clang/Analysis/Scalable/Model/EntityName.h (+47) 
- (modified) clang/lib/Analysis/CMakeLists.txt (+1) 
- (added) clang/lib/Analysis/Scalable/ASTEntityMapping.cpp (+85) 
- (added) clang/lib/Analysis/Scalable/CMakeLists.txt (+19) 
- (added) clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp (+72) 
- (added) clang/lib/Analysis/Scalable/Model/EntityName.cpp (+44) 
- (modified) clang/unittests/Analysis/CMakeLists.txt (+1) 
- (added) clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp (+343) 
- (added) clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp (+99) 
- (added) clang/unittests/Analysis/Scalable/CMakeLists.txt (+18) 
- (added) clang/unittests/Analysis/Scalable/EntityNameTest.cpp (+62) 


``diff
diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntityNameForFunctionReturn(const 
FunctionDecl* FD);
+
+} // namespace ssaf
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
diff --git a/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h 
b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
new file mode 100644
index 0..c4bf7146e461f
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
@@ -0,0 +1,84 @@
+//===- BuildNamespace.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_BUILD_NAMESPACE_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_BUILD_NAMESPACE_H
+
+#include "llvm/ADT/StringRef.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace ssaf {
+
+enum class BuildNamespaceKind : unsigned short {
+  CompilationUnit,
+  LinkUnit
+};
+
+std::string toString(BuildNamespaceKind BNK);
+
+std::optional parseBuildNamespaceKind(llvm::StringRef Str);
+
+/// Represents a single step in the build process.
+class BuildNamespace {
+  BuildNamespaceKind Kind;
+  std::string Name;
+public:
+  BuildNamespace(BuildNamespaceKind Kind, llvm::StringRef Name)
+: Kind(Kind), Nam

[clang] [clang][ssaf] Introduce entity abstraction for SSAF (PR #169131)

2025-11-21 Thread Jan Korous via cfe-commits

https://github.com/jkorous-apple created 
https://github.com/llvm/llvm-project/pull/169131

Add core abstractions for identifying program entities across compilation and 
link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying 
mechanism, with extensions for sub-entities (parameters, return values) via 
suffixes. The abstraction allows whole-program analysis by providing stable 
identifiers that persist across separately compiled translation units.

>From 61f84a4c4dfa70a4c4367c07075ac9a392cf70b4 Mon Sep 17 00:00:00 2001
From: Jan Korous 
Date: Fri, 21 Nov 2025 15:53:11 -0800
Subject: [PATCH] [clang][ssaf] Introduce entity abstraction for SSAF

Add core abstractions for identifying program entities across compilation
and link unit boundaries in the Scalable Static Analysis Framework (SSAF).

Introduces three key components:
- BuildNamespace: Represents build artifacts (compilation units, link units)
- EntityName: Globally unique entity identifiers across compilation boundaries
- AST mapping: Functions to map Clang AST declarations to EntityNames

Entity identification uses Unified Symbol Resolution (USR) as the underlying
mechanism, with extensions for sub-entities (parameters, return values) via
suffixes. The abstraction allows whole-program analysis by providing stable
identifiers that persist across separately compiled translation units.
---
 .../Analysis/Scalable/ASTEntityMapping.h  |  46 +++
 .../Analysis/Scalable/Model/BuildNamespace.h  |  84 +
 .../Analysis/Scalable/Model/EntityName.h  |  47 +++
 clang/lib/Analysis/CMakeLists.txt |   1 +
 .../Analysis/Scalable/ASTEntityMapping.cpp|  85 +
 clang/lib/Analysis/Scalable/CMakeLists.txt|  19 +
 .../Scalable/Model/BuildNamespace.cpp |  72 
 .../Analysis/Scalable/Model/EntityName.cpp|  44 +++
 clang/unittests/Analysis/CMakeLists.txt   |   1 +
 .../Scalable/ASTEntityMappingTest.cpp | 343 ++
 .../Analysis/Scalable/BuildNamespaceTest.cpp  |  99 +
 .../Analysis/Scalable/CMakeLists.txt  |  18 +
 .../Analysis/Scalable/EntityNameTest.cpp  |  62 
 13 files changed, 921 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/BuildNamespace.h
 create mode 100644 clang/include/clang/Analysis/Scalable/Model/EntityName.h
 create mode 100644 clang/lib/Analysis/Scalable/ASTEntityMapping.cpp
 create mode 100644 clang/lib/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/lib/Analysis/Scalable/Model/BuildNamespace.cpp
 create mode 100644 clang/lib/Analysis/Scalable/Model/EntityName.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/ASTEntityMappingTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/BuildNamespaceTest.cpp
 create mode 100644 clang/unittests/Analysis/Scalable/CMakeLists.txt
 create mode 100644 clang/unittests/Analysis/Scalable/EntityNameTest.cpp

diff --git a/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h 
b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
new file mode 100644
index 0..a137e8b741821
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/ASTEntityMapping.h
@@ -0,0 +1,46 @@
+//===- ASTMapping.h - AST to SSAF Entity mapping *- 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_ASTMAPPING_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_ASTMAPPING_H
+
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+namespace clang {
+namespace ssaf {
+
+/// Maps a declaration to an EntityName.
+///
+/// Supported declaration types for entity mapping:
+/// - Functions and methods
+/// - Global Variables
+/// - Function parameters
+/// - Struct/class/union type definitions
+/// - Struct/class/union fields
+///
+/// Implicit declarations and compiler builtins are not mapped.
+///
+/// \param D The declaration to map. Must not be null.
+///
+/// \return An EntityName if the declaration can be mapped, std::nullopt 
otherwise.
+std::optional getLocalEntityNameForDecl(const Decl* D);
+
+/// Maps a function return type to an EntityName.
+///
+/// \param FD The function declaration. Must not be null.
+///
+/// \return An EntityName for the function's return type.
+std::optional getLocalEntity