clang 24.0.0git
ASTEntityMapping.cpp
Go to the documentation of this file.
1//===- ASTMapping.cpp - AST to SSAF Entity mapping ------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements utilities for mapping AST declarations to SSAF entities.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Decl.h"
18#include "llvm/ADT/SmallString.h"
19#include "llvm/Support/ErrorHandling.h"
20
21namespace clang::ssaf {
22
23std::optional<EntityName> getEntityName(const Decl *D) {
24 if (!D)
25 return std::nullopt;
26
27 if (D->isImplicit())
28 return std::nullopt;
29
30 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->getBuiltinID())
31 return std::nullopt;
32
34 return std::nullopt;
35
37 const Decl *USRDecl = D;
38
39 // For parameters, use the parent function's USR with parameter index as
40 // suffix
41 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
42 const auto *FD =
43 dyn_cast_or_null<FunctionDecl>(PVD->getParentFunctionOrMethod());
44 if (!FD)
45 return std::nullopt;
46 USRDecl = FD;
47
48 const auto ParamIdx = PVD->getFunctionScopeIndex();
49 llvm::raw_svector_ostream OS(Suffix);
50 // Parameter uses function's USR with 1-based index as suffix
51 OS << (ParamIdx + 1);
52 }
53
55 if (clang::index::generateUSRForDecl(USRDecl, USRBuf))
56 return std::nullopt;
57
58 if (USRBuf.empty())
59 return std::nullopt;
60
61 return EntityName(USRBuf.str(), Suffix, {});
62}
63
64std::optional<EntityName> getEntityNameForReturn(const FunctionDecl *FD) {
65 if (!FD)
66 return std::nullopt;
67
68 if (FD->isImplicit())
69 return std::nullopt;
70
71 if (FD->getBuiltinID())
72 return std::nullopt;
73
75 if (clang::index::generateUSRForDecl(FD, USRBuf)) {
76 return std::nullopt;
77 }
78
79 if (USRBuf.empty())
80 return std::nullopt;
81
82 return EntityName(USRBuf.str(), /*Suffix=*/"0", /*Namespace=*/{});
83}
84
86 const auto *ND = dyn_cast<NamedDecl>(D);
87 if (!ND)
89
90 // Parameters have no linkage in C++, but SSAF needs them to inherit
91 // the external linkage from their parent functions.
92 // Here is why:
93 // SSAF treats parameters as entities and may not always associate them back
94 // to their parent functions. Therefore, it needs to identify parameters of
95 // functions with external linkage across different TUs. Treating them as
96 // having no linkage (as in C++) causes the same parameter in different TUs
97 // to be assigned different EntityIDs. As a result, the behavior of the
98 // parameter across multiple TUs cannot be correlated.
99 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
100 if (const auto *FD = llvm::dyn_cast_or_null<FunctionDecl>(
101 PVD->getParentFunctionOrMethod())) {
102 return getLinkageForDecl(FD);
103 }
104 }
105
106 switch (ND->getFormalLinkage()) {
107 case Linkage::Invalid: {
108 llvm_unreachable("Shouldn't be invalid");
109 }
110 case Linkage::None:
118 case Linkage::Module:
122 }
123 llvm_unreachable("Unhandled clang::Linkage kind");
124}
125
126std::optional<EntityName>
128 const NestedBuildNamespace &LUNamespace) {
129 std::optional<EntityName> Name = getEntityName(D);
130 if (!Name)
131 return std::nullopt;
132 return Name->makeQualified(resolveNamespace(
133 LUNamespace, TUNamespace, /*EntityNamespace=*/{}, getLinkageForDecl(D)));
134}
135
136std::optional<EntityName>
138 const NestedBuildNamespace &TUNamespace,
139 const NestedBuildNamespace &LUNamespace) {
140 std::optional<EntityName> Name = getEntityNameForReturn(FD);
141 if (!Name)
142 return std::nullopt;
143 return Name->makeQualified(resolveNamespace(
144 LUNamespace, TUNamespace, /*EntityNamespace=*/{}, getLinkageForDecl(FD)));
145}
146
147} // namespace clang::ssaf
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
Represents a function declaration or definition.
Definition Decl.h:2059
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3804
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
Definition Attr.h:279
Uniquely identifies an entity in a program.
Definition EntityName.h:28
Represents a hierarchical sequence of build namespaces.
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
std::optional< EntityName > getEntityNameForReturn(const FunctionDecl *FD)
Maps return entity of a function to an EntityName.
EntityLinkageType getLinkageForDecl(const Decl *D)
Computes the SSAF linkage of a declaration.
std::optional< EntityName > getQualifiedEntityNameForReturn(const FunctionDecl *FD, const NestedBuildNamespace &TUNamespace, const NestedBuildNamespace &LUNamespace)
Similar to getQualifiedEntityName, but for entities of function return values.
std::optional< EntityName > getQualifiedEntityName(const Decl *D, const NestedBuildNamespace &TUNamespace, const NestedBuildNamespace &LUNamespace)
Returns the EntityName qualified with the build namespaces it would carry after linking into LUNamesp...
std::optional< EntityName > getEntityName(const Decl *D)
Maps a declaration to an EntityName.
NestedBuildNamespace resolveNamespace(const NestedBuildNamespace &LUNamespace, const NestedBuildNamespace &TUNamespace, const NestedBuildNamespace &EntityNamespace, EntityLinkageType Linkage)
Computes the build namespace an entity should carry after linking, given its linkage.
@ Internal
static functions/variables, anonymous namespace
@ External
globally visible across translation units (including parameters of functions with external linkage)
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ VisibleNone
No linkage according to the standard, but is visible from other translation units because of types de...
Definition Linkage.h:48
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
Definition Linkage.h:30
@ UniqueExternal
External linkage within a unique namespace.
Definition Linkage.h:44
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition Linkage.h:35
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
Definition Linkage.h:58
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
Definition Linkage.h:54
U cast(CodeGen::Address addr)
Definition Address.h:327