xref: /freebsd/contrib/llvm-project/clang/include/clang/Basic/Builtins.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===--- Builtins.h - Builtin function header -------------------*- C++ -*-===//
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 /// \file
10 /// Defines enum values for all the target-independent builtin
11 /// functions.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_BASIC_BUILTINS_H
16 #define LLVM_CLANG_BASIC_BUILTINS_H
17 
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/StringTable.h"
22 #include <cstring>
23 
24 // VC++ defines 'alloca' as an object-like macro, which interferes with our
25 // builtins.
26 #undef alloca
27 
28 namespace clang {
29 class TargetInfo;
30 class IdentifierTable;
31 class LangOptions;
32 
33 enum LanguageID : uint16_t {
34   GNU_LANG = 0x1,            // builtin requires GNU mode.
35   C_LANG = 0x2,              // builtin for c only.
36   CXX_LANG = 0x4,            // builtin for cplusplus only.
37   OBJC_LANG = 0x8,           // builtin for objective-c and objective-c++
38   MS_LANG = 0x10,            // builtin requires MS mode.
39   OMP_LANG = 0x20,           // builtin requires OpenMP.
40   CUDA_LANG = 0x40,          // builtin requires CUDA.
41   COR_LANG = 0x80,           // builtin requires use of 'fcoroutine-ts' option.
42   OCL_GAS = 0x100,           // builtin requires OpenCL generic address space.
43   OCL_PIPE = 0x200,          // builtin requires OpenCL pipe.
44   OCL_DSE = 0x400,           // builtin requires OpenCL device side enqueue.
45   ALL_OCL_LANGUAGES = 0x800, // builtin for OCL languages.
46   HLSL_LANG = 0x1000,        // builtin requires HLSL.
47   C23_LANG = 0x2000,         // builtin requires C23 or later.
48   ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
49   ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG,  // builtin requires GNU mode.
50   ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG     // builtin requires MS mode.
51 };
52 
53 struct HeaderDesc {
54   enum HeaderID : uint16_t {
55 #define HEADER(ID, NAME) ID,
56 #include "clang/Basic/BuiltinHeaders.def"
57 #undef HEADER
58   } ID;
59 
HeaderDescHeaderDesc60   constexpr HeaderDesc() : ID() {}
HeaderDescHeaderDesc61   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
62 
63   const char *getName() const;
64 };
65 
66 namespace Builtin {
67 enum ID {
68   NotBuiltin = 0, // This is not a builtin function.
69 #define GET_BUILTIN_ENUMERATORS
70 #include "clang/Basic/Builtins.inc"
71 #undef GET_BUILTIN_ENUMERATORS
72   FirstTSBuiltin
73 };
74 
75 struct InfosShard;
76 
77 /// The info used to represent each builtin.
78 struct Info {
79   // Rather than store pointers to the string literals describing these four
80   // aspects of builtins, we store offsets into a common string table.
81   struct StrOffsets {
82     llvm::StringTable::Offset Name = {};
83     llvm::StringTable::Offset Type = {};
84     llvm::StringTable::Offset Attributes = {};
85 
86     // Defaults to the empty string offset.
87     llvm::StringTable::Offset Features = {};
88   } Offsets;
89 
90   HeaderDesc Header = HeaderDesc::NO_HEADER;
91   LanguageID Langs = ALL_LANGUAGES;
92 
93   /// Get the name for the builtin represented by this `Info` object.
94   ///
95   /// Must be provided the `Shard` for this `Info` object.
96   std::string getName(const InfosShard &Shard) const;
97 };
98 
99 /// A constexpr function to construct an infos array from X-macros.
100 ///
101 /// The input array uses the same data structure, but the offsets are actually
102 /// _lengths_ when input. This is all we can compute from the X-macro approach
103 /// to builtins. This function will convert these lengths into actual offsets to
104 /// a string table built up through sequentially appending strings with the
105 /// given lengths.
106 template <size_t N>
MakeInfos(std::array<Info,N> Infos)107 static constexpr std::array<Info, N> MakeInfos(std::array<Info, N> Infos) {
108   // Translate lengths to offsets. We start past the initial empty string at
109   // offset zero.
110   unsigned Offset = 1;
111   for (Info &I : Infos) {
112     Info::StrOffsets NewOffsets = {};
113     NewOffsets.Name = Offset;
114     Offset += I.Offsets.Name.value();
115     NewOffsets.Type = Offset;
116     Offset += I.Offsets.Type.value();
117     NewOffsets.Attributes = Offset;
118     Offset += I.Offsets.Attributes.value();
119     NewOffsets.Features = Offset;
120     Offset += I.Offsets.Features.value();
121     I.Offsets = NewOffsets;
122   }
123   return Infos;
124 }
125 
126 /// A shard of a target's builtins string table and info.
127 ///
128 /// Target builtins are sharded across multiple tables due to different
129 /// structures, origins, and also to improve the overall scaling by avoiding a
130 /// single table across all builtins.
131 struct InfosShard {
132   const llvm::StringTable *Strings;
133   llvm::ArrayRef<Info> Infos;
134 
135   llvm::StringLiteral NamePrefix = "";
136 };
137 
138 // A detail macro used below to emit a string literal that, after string literal
139 // concatenation, ends up triggering the `-Woverlength-strings` warning. While
140 // the warning is useful in general to catch accidentally excessive strings,
141 // here we are creating them intentionally.
142 //
143 // This relies on a subtle aspect of `_Pragma`: that the *diagnostic* ones don't
144 // turn into actual tokens that would disrupt string literal concatenation.
145 #ifdef __clang__
146 #define CLANG_BUILTIN_DETAIL_STR_TABLE(S)                                      \
147   _Pragma("clang diagnostic push")                                             \
148       _Pragma("clang diagnostic ignored \"-Woverlength-strings\"")             \
149           S _Pragma("clang diagnostic pop")
150 #else
151 #define CLANG_BUILTIN_DETAIL_STR_TABLE(S) S
152 #endif
153 
154 // We require string tables to start with an empty string so that a `0` offset
155 // can always be used to refer to an empty string. To satisfy that when building
156 // string tables with X-macros, we use this start macro prior to expanding the
157 // X-macros.
158 #define CLANG_BUILTIN_STR_TABLE_START CLANG_BUILTIN_DETAIL_STR_TABLE("\0")
159 
160 // A macro that can be used with `Builtins.def` and similar files as an X-macro
161 // to add the string arguments to a builtin string table. This is typically the
162 // target for the `BUILTIN`, `LANGBUILTIN`, or `LIBBUILTIN` macros in those
163 // files.
164 #define CLANG_BUILTIN_STR_TABLE(ID, TYPE, ATTRS)                               \
165   CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" /*FEATURE*/ "\0")
166 
167 // A macro that can be used with target builtin `.def` and `.inc` files as an
168 // X-macro to add the string arguments to a builtin string table. this is
169 // typically the target for the `TARGET_BUILTIN` macro.
170 #define CLANG_TARGET_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, FEATURE)               \
171   CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0")
172 
173 // A macro that can be used with target builtin `.def` and `.inc` files as an
174 // X-macro to add the string arguments to a builtin string table. this is
175 // typically the target for the `TARGET_HEADER_BUILTIN` macro. We can't delegate
176 // to `TARGET_BUILTIN` because the `FEATURE` string changes position.
177 #define CLANG_TARGET_HEADER_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, HEADER, LANGS,  \
178                                               FEATURE)                         \
179   CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0")
180 
181 // A detail macro used internally to compute the desired string table
182 // `StrOffsets` struct for arguments to `MakeInfos`.
183 #define CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS)                      \
184   Builtin::Info::StrOffsets {                                                  \
185     sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
186   }
187 
188 // A detail macro used internally to compute the desired string table
189 // `StrOffsets` struct for arguments to `Storage::Make`.
190 #define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
191   Builtin::Info::StrOffsets {                                                  \
192     sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
193   }
194 
195 // A set of macros that can be used with builtin `.def' files as an X-macro to
196 // create an `Info` struct for a particular builtin. It both computes the
197 // `StrOffsets` value for the string table (the lengths here, translated to
198 // offsets by the `MakeInfos` function), and the other metadata for each
199 // builtin.
200 //
201 // There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
202 // `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
203 #define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
204   Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
205                 HeaderDesc::NO_HEADER, ALL_LANGUAGES},
206 #define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
207   Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
208                 HeaderDesc::NO_HEADER, LANG},
209 #define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
210   Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
211                 HeaderDesc::HEADER, LANG},
212 #define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
213   Builtin::Info{                                                               \
214       CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
215       HeaderDesc::NO_HEADER, ALL_LANGUAGES},
216 #define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
217                                           FEATURE)                             \
218   Builtin::Info{                                                               \
219       CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
220       HeaderDesc::HEADER, LANG},
221 
222 /// Holds information about both target-independent and
223 /// target-specific builtins, allowing easy queries by clients.
224 ///
225 /// Builtins from an optional auxiliary target are stored in
226 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
227 /// be translated back with getAuxBuiltinID() before use.
228 class Context {
229   llvm::SmallVector<InfosShard> BuiltinShards;
230 
231   llvm::SmallVector<InfosShard> TargetShards;
232   llvm::SmallVector<InfosShard> AuxTargetShards;
233 
234   unsigned NumTargetBuiltins = 0;
235   unsigned NumAuxTargetBuiltins = 0;
236 
237 public:
238   Context();
239 
240   /// Perform target-specific initialization
241   /// \param AuxTarget Target info to incorporate builtins from. May be nullptr.
242   void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget);
243 
244   /// Mark the identifiers for all the builtins with their
245   /// appropriate builtin ID # and mark any non-portable builtin identifiers as
246   /// such.
247   void initializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts);
248 
249   /// Return the identifier name for the specified builtin,
250   /// e.g. "__builtin_abs".
251   std::string getName(unsigned ID) const;
252 
253   /// Return the identifier name for the specified builtin inside single quotes
254   /// for a diagnostic, e.g. "'__builtin_abs'".
255   std::string getQuotedName(unsigned ID) const;
256 
257   /// Get the type descriptor string for the specified builtin.
258   const char *getTypeString(unsigned ID) const;
259 
260   /// Get the attributes descriptor string for the specified builtin.
261   const char *getAttributesString(unsigned ID) const;
262 
263   /// Return true if this function is a target-specific builtin.
isTSBuiltin(unsigned ID)264   bool isTSBuiltin(unsigned ID) const {
265     return ID >= Builtin::FirstTSBuiltin;
266   }
267 
268   /// Return true if this function has no side effects.
isPure(unsigned ID)269   bool isPure(unsigned ID) const {
270     return strchr(getAttributesString(ID), 'U') != nullptr;
271   }
272 
273   /// Return true if this function has no side effects and doesn't
274   /// read memory.
isConst(unsigned ID)275   bool isConst(unsigned ID) const {
276     return strchr(getAttributesString(ID), 'c') != nullptr;
277   }
278 
279   /// Return true if we know this builtin never throws an exception.
isNoThrow(unsigned ID)280   bool isNoThrow(unsigned ID) const {
281     return strchr(getAttributesString(ID), 'n') != nullptr;
282   }
283 
284   /// Return true if we know this builtin never returns.
isNoReturn(unsigned ID)285   bool isNoReturn(unsigned ID) const {
286     return strchr(getAttributesString(ID), 'r') != nullptr;
287   }
288 
289   /// Return true if we know this builtin can return twice.
isReturnsTwice(unsigned ID)290   bool isReturnsTwice(unsigned ID) const {
291     return strchr(getAttributesString(ID), 'j') != nullptr;
292   }
293 
294   /// Returns true if this builtin does not perform the side-effects
295   /// of its arguments.
isUnevaluated(unsigned ID)296   bool isUnevaluated(unsigned ID) const {
297     return strchr(getAttributesString(ID), 'u') != nullptr;
298   }
299 
300   /// Return true if this is a builtin for a libc/libm function,
301   /// with a "__builtin_" prefix (e.g. __builtin_abs).
isLibFunction(unsigned ID)302   bool isLibFunction(unsigned ID) const {
303     return strchr(getAttributesString(ID), 'F') != nullptr;
304   }
305 
306   /// Determines whether this builtin is a predefined libc/libm
307   /// function, such as "malloc", where we know the signature a
308   /// priori.
309   /// In C, such functions behave as if they are predeclared,
310   /// possibly with a warning on first use. In Objective-C and C++,
311   /// they do not, but they are recognized as builtins once we see
312   /// a declaration.
isPredefinedLibFunction(unsigned ID)313   bool isPredefinedLibFunction(unsigned ID) const {
314     return strchr(getAttributesString(ID), 'f') != nullptr;
315   }
316 
317   /// Returns true if this builtin requires appropriate header in other
318   /// compilers. In Clang it will work even without including it, but we can emit
319   /// a warning about missing header.
isHeaderDependentFunction(unsigned ID)320   bool isHeaderDependentFunction(unsigned ID) const {
321     return strchr(getAttributesString(ID), 'h') != nullptr;
322   }
323 
324   /// Determines whether this builtin is a predefined compiler-rt/libgcc
325   /// function, such as "__clear_cache", where we know the signature a
326   /// priori.
isPredefinedRuntimeFunction(unsigned ID)327   bool isPredefinedRuntimeFunction(unsigned ID) const {
328     return strchr(getAttributesString(ID), 'i') != nullptr;
329   }
330 
331   /// Determines whether this builtin is a C++ standard library function
332   /// that lives in (possibly-versioned) namespace std, possibly a template
333   /// specialization, where the signature is determined by the standard library
334   /// declaration.
isInStdNamespace(unsigned ID)335   bool isInStdNamespace(unsigned ID) const {
336     return strchr(getAttributesString(ID), 'z') != nullptr;
337   }
338 
339   /// Determines whether this builtin can have its address taken with no
340   /// special action required.
isDirectlyAddressable(unsigned ID)341   bool isDirectlyAddressable(unsigned ID) const {
342     // Most standard library functions can have their addresses taken. C++
343     // standard library functions formally cannot in C++20 onwards, and when
344     // we allow it, we need to ensure we instantiate a definition.
345     return isPredefinedLibFunction(ID) && !isInStdNamespace(ID);
346   }
347 
348   /// Determines whether this builtin has custom typechecking.
hasCustomTypechecking(unsigned ID)349   bool hasCustomTypechecking(unsigned ID) const {
350     return strchr(getAttributesString(ID), 't') != nullptr;
351   }
352 
353   /// Determines whether a declaration of this builtin should be recognized
354   /// even if the type doesn't match the specified signature.
allowTypeMismatch(unsigned ID)355   bool allowTypeMismatch(unsigned ID) const {
356     return strchr(getAttributesString(ID), 'T') != nullptr ||
357            hasCustomTypechecking(ID);
358   }
359 
360   /// Determines whether this builtin has a result or any arguments which
361   /// are pointer types.
hasPtrArgsOrResult(unsigned ID)362   bool hasPtrArgsOrResult(unsigned ID) const {
363     return strchr(getTypeString(ID), '*') != nullptr;
364   }
365 
366   /// Return true if this builtin has a result or any arguments which are
367   /// reference types.
hasReferenceArgsOrResult(unsigned ID)368   bool hasReferenceArgsOrResult(unsigned ID) const {
369     return strchr(getTypeString(ID), '&') != nullptr ||
370            strchr(getTypeString(ID), 'A') != nullptr;
371   }
372 
373   /// If this is a library function that comes from a specific
374   /// header, retrieve that header name.
getHeaderName(unsigned ID)375   const char *getHeaderName(unsigned ID) const {
376     return getInfo(ID).Header.getName();
377   }
378 
379   /// Determine whether this builtin is like printf in its
380   /// formatting rules and, if so, set the index to the format string
381   /// argument and whether this function as a va_list argument.
382   bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
383 
384   /// Determine whether this builtin is like scanf in its
385   /// formatting rules and, if so, set the index to the format string
386   /// argument and whether this function as a va_list argument.
387   bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
388 
389   /// Determine whether this builtin has callback behavior (see
390   /// llvm::AbstractCallSites for details). If so, add the index to the
391   /// callback callee argument and the callback payload arguments.
392   bool performsCallback(unsigned ID,
393                         llvm::SmallVectorImpl<int> &Encoding) const;
394 
395   /// Return true if this function has no side effects and doesn't
396   /// read memory, except for possibly errno or raising FP exceptions.
397   ///
398   /// Such functions can be const when the MathErrno lang option and FP
399   /// exceptions are disabled.
isConstWithoutErrnoAndExceptions(unsigned ID)400   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
401     return strchr(getAttributesString(ID), 'e') != nullptr;
402   }
403 
isConstWithoutExceptions(unsigned ID)404   bool isConstWithoutExceptions(unsigned ID) const {
405     return strchr(getAttributesString(ID), 'g') != nullptr;
406   }
407 
408   const char *getRequiredFeatures(unsigned ID) const;
409 
410   unsigned getRequiredVectorWidth(unsigned ID) const;
411 
412   /// Return true if the builtin ID belongs exclusively to the AuxTarget,
413   /// and false if it belongs to both primary and aux target, or neither.
isAuxBuiltinID(unsigned ID)414   bool isAuxBuiltinID(unsigned ID) const {
415     return ID >= (Builtin::FirstTSBuiltin + NumTargetBuiltins);
416   }
417 
418   /// Return real builtin ID (i.e. ID it would have during compilation
419   /// for AuxTarget).
getAuxBuiltinID(unsigned ID)420   unsigned getAuxBuiltinID(unsigned ID) const { return ID - NumTargetBuiltins; }
421 
422   /// Returns true if this is a libc/libm function without the '__builtin_'
423   /// prefix.
424   static bool isBuiltinFunc(llvm::StringRef Name);
425 
426   /// Returns true if this is a builtin that can be redeclared.  Returns true
427   /// for non-builtins.
428   bool canBeRedeclared(unsigned ID) const;
429 
430   /// Return true if this function can be constant evaluated by Clang frontend.
isConstantEvaluated(unsigned ID)431   bool isConstantEvaluated(unsigned ID) const {
432     return strchr(getAttributesString(ID), 'E') != nullptr;
433   }
434 
435   /// Returns true if this is an immediate (consteval) function
isImmediate(unsigned ID)436   bool isImmediate(unsigned ID) const {
437     return strchr(getAttributesString(ID), 'G') != nullptr;
438   }
439 
440 private:
441   std::pair<const InfosShard &, const Info &>
442   getShardAndInfo(unsigned ID) const;
443 
getInfo(unsigned ID)444   const Info &getInfo(unsigned ID) const { return getShardAndInfo(ID).second; }
445 
446   /// Helper function for isPrintfLike and isScanfLike.
447   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
448               const char *Fmt) const;
449 };
450 
451 /// Returns true if the required target features of a builtin function are
452 /// enabled.
453 /// \p TargetFeatureMap maps a target feature to true if it is enabled and
454 ///    false if it is disabled.
455 bool evaluateRequiredTargetFeatures(
456     llvm::StringRef RequiredFatures,
457     const llvm::StringMap<bool> &TargetFetureMap);
458 
459 } // namespace Builtin
460 
461 /// Kinds of BuiltinTemplateDecl.
462 enum BuiltinTemplateKind : int {
463 #define BuiltinTemplate(BTName) BTK##BTName,
464 #include "clang/Basic/BuiltinTemplates.inc"
465 };
466 
467 } // end namespace clang
468 #endif
469