clang 20.0.0git
Builtins.cpp
Go to the documentation of this file.
1//===--- Builtins.cpp - Builtin function implementation -------------------===//
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 various things for builtin functions.
10//
11//===----------------------------------------------------------------------===//
12
18#include "llvm/ADT/StringRef.h"
19using namespace clang;
20
21const char *HeaderDesc::getName() const {
22 switch (ID) {
23#define HEADER(ID, NAME) \
24 case ID: \
25 return NAME;
26#include "clang/Basic/BuiltinHeaders.def"
27#undef HEADER
28 };
29 llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
30}
31
32static constexpr Builtin::Info BuiltinInfo[] = {
33 {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
35#define BUILTIN(ID, TYPE, ATTRS) \
36 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
37#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \
38 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
39#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS) \
40 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
41#include "clang/Basic/Builtins.inc"
42};
43
44const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
46 return BuiltinInfo[ID];
47 assert(((ID - Builtin::FirstTSBuiltin) <
48 (TSRecords.size() + AuxTSRecords.size())) &&
49 "Invalid builtin ID!");
50 if (isAuxBuiltinID(ID))
51 return AuxTSRecords[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin];
52 return TSRecords[ID - Builtin::FirstTSBuiltin];
53}
54
56 const TargetInfo *AuxTarget) {
57 assert(TSRecords.empty() && "Already initialized target?");
58 TSRecords = Target.getTargetBuiltins();
59 if (AuxTarget)
60 AuxTSRecords = AuxTarget->getTargetBuiltins();
61}
62
63bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) {
64 bool InStdNamespace = FuncName.consume_front("std-");
65 for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin;
66 ++i) {
67 if (FuncName == BuiltinInfo[i].Name &&
68 (bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace)
69 return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr;
70 }
71
72 return false;
73}
74
75/// Is this builtin supported according to the given language options?
77 const LangOptions &LangOpts) {
78 /* Builtins Unsupported */
79 if (LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr)
80 return false;
81 /* CorBuiltins Unsupported */
82 if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG))
83 return false;
84 /* MathBuiltins Unsupported */
85 if (LangOpts.NoMathBuiltin && BuiltinInfo.Header.ID == HeaderDesc::MATH_H)
86 return false;
87 /* GnuMode Unsupported */
88 if (!LangOpts.GNUMode && (BuiltinInfo.Langs & GNU_LANG))
89 return false;
90 /* MSMode Unsupported */
91 if (!LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG))
92 return false;
93 /* ObjC Unsupported */
94 if (!LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG)
95 return false;
96 /* OpenCLC Unsupported */
97 if (!LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCL_LANGUAGES))
98 return false;
99 /* OopenCL GAS Unsupported */
100 if (!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.Langs & OCL_GAS))
101 return false;
102 /* OpenCL Pipe Unsupported */
103 if (!LangOpts.OpenCLPipes && (BuiltinInfo.Langs & OCL_PIPE))
104 return false;
105
106 // Device side enqueue is not supported until OpenCL 2.0. In 2.0 and higher
107 // support is indicated with language option for blocks.
108
109 /* OpenCL DSE Unsupported */
110 if ((LangOpts.getOpenCLCompatibleVersion() < 200 || !LangOpts.Blocks) &&
112 return false;
113 /* OpenMP Unsupported */
114 if (!LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG)
115 return false;
116 /* CUDA Unsupported */
117 if (!LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG)
118 return false;
119 /* CPlusPlus Unsupported */
120 if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
121 return false;
122 /* consteval Unsupported */
123 if (!LangOpts.CPlusPlus20 && strchr(BuiltinInfo.Attributes, 'G') != nullptr)
124 return false;
125 return true;
126}
127
128/// initializeBuiltins - Mark the identifiers for all the builtins with their
129/// appropriate builtin ID # and mark any non-portable builtin identifiers as
130/// such.
132 const LangOptions& LangOpts) {
133 // Step #1: mark all target-independent builtins with their ID's.
134 for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
135 if (builtinIsSupported(BuiltinInfo[i], LangOpts)) {
136 Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
137 }
138
139 // Step #2: Register target-specific builtins.
140 for (unsigned i = 0, e = TSRecords.size(); i != e; ++i)
141 if (builtinIsSupported(TSRecords[i], LangOpts))
142 Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin);
143
144 // Step #3: Register target-specific builtins for AuxTarget.
145 for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i)
146 Table.get(AuxTSRecords[i].Name)
147 .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size());
148
149 // Step #4: Unregister any builtins specified by -fno-builtin-foo.
150 for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) {
151 bool InStdNamespace = Name.consume_front("std-");
152 auto NameIt = Table.find(Name);
153 if (NameIt != Table.end()) {
154 unsigned ID = NameIt->second->getBuiltinID();
155 if (ID != Builtin::NotBuiltin && isPredefinedLibFunction(ID) &&
156 isInStdNamespace(ID) == InStdNamespace) {
157 NameIt->second->clearBuiltinID();
158 }
159 }
160 }
161}
162
164 const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V');
165 if (!WidthPos)
166 return 0;
167
168 ++WidthPos;
169 assert(*WidthPos == ':' &&
170 "Vector width specifier must be followed by a ':'");
171 ++WidthPos;
172
173 char *EndPos;
174 unsigned Width = ::strtol(WidthPos, &EndPos, 10);
175 assert(*EndPos == ':' && "Vector width specific must end with a ':'");
176 return Width;
177}
178
179bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx,
180 bool &HasVAListArg, const char *Fmt) const {
181 assert(Fmt && "Not passed a format string");
182 assert(::strlen(Fmt) == 2 &&
183 "Format string needs to be two characters long");
184 assert(::toupper(Fmt[0]) == Fmt[1] &&
185 "Format string is not in the form \"xX\"");
186
187 const char *Like = ::strpbrk(getRecord(ID).Attributes, Fmt);
188 if (!Like)
189 return false;
190
191 HasVAListArg = (*Like == Fmt[1]);
192
193 ++Like;
194 assert(*Like == ':' && "Format specifier must be followed by a ':'");
195 ++Like;
196
197 assert(::strchr(Like, ':') && "Format specifier must end with a ':'");
198 FormatIdx = ::strtol(Like, nullptr, 10);
199 return true;
200}
201
202bool Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
203 bool &HasVAListArg) {
204 return isLike(ID, FormatIdx, HasVAListArg, "pP");
205}
206
207bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
208 bool &HasVAListArg) {
209 return isLike(ID, FormatIdx, HasVAListArg, "sS");
210}
211
213 SmallVectorImpl<int> &Encoding) const {
214 const char *CalleePos = ::strchr(getRecord(ID).Attributes, 'C');
215 if (!CalleePos)
216 return false;
217
218 ++CalleePos;
219 assert(*CalleePos == '<' &&
220 "Callback callee specifier must be followed by a '<'");
221 ++CalleePos;
222
223 char *EndPos;
224 int CalleeIdx = ::strtol(CalleePos, &EndPos, 10);
225 assert(CalleeIdx >= 0 && "Callee index is supposed to be positive!");
226 Encoding.push_back(CalleeIdx);
227
228 while (*EndPos == ',') {
229 const char *PayloadPos = EndPos + 1;
230
231 int PayloadIdx = ::strtol(PayloadPos, &EndPos, 10);
232 Encoding.push_back(PayloadIdx);
233 }
234
235 assert(*EndPos == '>' && "Callback callee specifier must end with a '>'");
236 return true;
237}
238
240 return ID == Builtin::NotBuiltin || ID == Builtin::BI__va_start ||
241 ID == Builtin::BI__builtin_assume_aligned ||
242 (!hasReferenceArgsOrResult(ID) && !hasCustomTypechecking(ID)) ||
243 isInStdNamespace(ID);
244}
245
247 StringRef RequiredFeatures, const llvm::StringMap<bool> &TargetFetureMap) {
248 // Return true if the builtin doesn't have any required features.
249 if (RequiredFeatures.empty())
250 return true;
251 assert(!RequiredFeatures.contains(' ') && "Space in feature list");
252
253 TargetFeatures TF(TargetFetureMap);
254 return TF.hasRequiredFeatures(RequiredFeatures);
255}
static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, const LangOptions &LangOpts)
Is this builtin supported according to the given language options?
Definition: Builtins.cpp:76
static constexpr Builtin::Info BuiltinInfo[]
Definition: Builtins.cpp:32
Defines enum values for all the target-independent builtin functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Definition: MachO.h:51
bool performsCallback(unsigned ID, llvm::SmallVectorImpl< int > &Encoding) const
Determine whether this builtin has callback behavior (see llvm::AbstractCallSites for details).
Definition: Builtins.cpp:212
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
Definition: Builtins.h:262
static bool isBuiltinFunc(llvm::StringRef Name)
Returns true if this is a libc/libm function without the '__builtin_' prefix.
Definition: Builtins.cpp:63
unsigned getRequiredVectorWidth(unsigned ID) const
Definition: Builtins.cpp:163
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
Definition: Builtins.h:268
void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)
Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...
Definition: Builtins.cpp:131
bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg)
Determine whether this builtin is like scanf in its formatting rules and, if so, set the index to the...
Definition: Builtins.cpp:207
bool canBeRedeclared(unsigned ID) const
Returns true if this is a builtin that can be redeclared.
Definition: Builtins.cpp:239
bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg)
Determine whether this builtin is like printf in its formatting rules and, if so, set the index to th...
Definition: Builtins.cpp:202
void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget)
Perform target-specific initialization.
Definition: Builtins.cpp:55
TargetFeatures - This class is used to check whether the builtin function has the required tagert spe...
void setBuiltinID(unsigned ID)
Implements an efficient mapping from strings to IdentifierInfo nodes.
iterator find(StringRef Name) const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
iterator end() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:461
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
Definition: LangOptions.h:528
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Definition: LangOptions.cpp:63
Exposes information about the current target.
Definition: TargetInfo.h:218
virtual ArrayRef< Builtin::Info > getTargetBuiltins() const =0
Return information about target-specific builtins for the current primary target, and info about whic...
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
The JSON file list parser is used to communicate input to InstallAPI.
@ ALL_LANGUAGES
Definition: Builtins.h:46
@ MS_LANG
Definition: Builtins.h:37
@ CUDA_LANG
Definition: Builtins.h:39
@ OMP_LANG
Definition: Builtins.h:38
@ CXX_LANG
Definition: Builtins.h:35
@ OBJC_LANG
Definition: Builtins.h:36
@ OCL_DSE
Definition: Builtins.h:43
@ ALL_OCL_LANGUAGES
Definition: Builtins.h:44
@ OCL_GAS
Definition: Builtins.h:41
@ GNU_LANG
Definition: Builtins.h:33
@ COR_LANG
Definition: Builtins.h:40
@ OCL_PIPE
Definition: Builtins.h:42
HeaderDesc Header
Definition: Builtins.h:75
LanguageID Langs
Definition: Builtins.h:76
const char * Attributes
Definition: Builtins.h:73
const char * getName() const
Definition: Builtins.cpp:21
enum clang::HeaderDesc::HeaderID ID