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 <cstring> |
20 | |
21 | // VC++ defines 'alloca' as an object-like macro, which interferes with our |
22 | // builtins. |
23 | #undef alloca |
24 | |
25 | namespace clang { |
26 | class TargetInfo; |
27 | class IdentifierTable; |
28 | class ASTContext; |
29 | class QualType; |
30 | class LangOptions; |
31 | |
32 | enum LanguageID { |
33 | GNU_LANG = 0x1, // builtin requires GNU mode. |
34 | C_LANG = 0x2, // builtin for c only. |
35 | CXX_LANG = 0x4, // builtin for cplusplus only. |
36 | OBJC_LANG = 0x8, // builtin for objective-c and objective-c++ |
37 | MS_LANG = 0x10, // builtin requires MS mode. |
38 | OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only. |
39 | OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only. |
40 | OMP_LANG = 0x80, // builtin requires OpenMP. |
41 | ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages. |
42 | ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode. |
43 | ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG, // builtin requires MS mode. |
44 | ALL_OCLC_LANGUAGES = OCLC1X_LANG | OCLC20_LANG // builtin for OCLC languages. |
45 | }; |
46 | |
47 | namespace Builtin { |
48 | enum ID { |
49 | NotBuiltin = 0, // This is not a builtin function. |
50 | #define BUILTIN(ID, TYPE, ATTRS) BI##ID, |
51 | #include "clang/Basic/Builtins.def" |
52 | FirstTSBuiltin |
53 | }; |
54 | |
55 | struct Info { |
56 | const char *Name, *Type, *Attributes, *HeaderName; |
57 | LanguageID Langs; |
58 | const char *Features; |
59 | }; |
60 | |
61 | /// Holds information about both target-independent and |
62 | /// target-specific builtins, allowing easy queries by clients. |
63 | /// |
64 | /// Builtins from an optional auxiliary target are stored in |
65 | /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to |
66 | /// be translated back with getAuxBuiltinID() before use. |
67 | class Context { |
68 | llvm::ArrayRef<Info> TSRecords; |
69 | llvm::ArrayRef<Info> AuxTSRecords; |
70 | |
71 | public: |
72 | Context() {} |
73 | |
74 | /// Perform target-specific initialization |
75 | /// \param AuxTarget Target info to incorporate builtins from. May be nullptr. |
76 | void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget); |
77 | |
78 | /// Mark the identifiers for all the builtins with their |
79 | /// appropriate builtin ID # and mark any non-portable builtin identifiers as |
80 | /// such. |
81 | void initializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts); |
82 | |
83 | /// Return the identifier name for the specified builtin, |
84 | /// e.g. "__builtin_abs". |
85 | const char *getName(unsigned ID) const { |
86 | return getRecord(ID).Name; |
87 | } |
88 | |
89 | /// Get the type descriptor string for the specified builtin. |
90 | const char *getTypeString(unsigned ID) const { |
91 | return getRecord(ID).Type; |
92 | } |
93 | |
94 | /// Return true if this function is a target-specific builtin. |
95 | bool isTSBuiltin(unsigned ID) const { |
96 | return ID >= Builtin::FirstTSBuiltin; |
97 | } |
98 | |
99 | /// Return true if this function has no side effects. |
100 | bool isPure(unsigned ID) const { |
101 | return strchr(getRecord(ID).Attributes, 'U') != nullptr; |
102 | } |
103 | |
104 | /// Return true if this function has no side effects and doesn't |
105 | /// read memory. |
106 | bool isConst(unsigned ID) const { |
107 | return strchr(getRecord(ID).Attributes, 'c') != nullptr; |
108 | } |
109 | |
110 | /// Return true if we know this builtin never throws an exception. |
111 | bool isNoThrow(unsigned ID) const { |
112 | return strchr(getRecord(ID).Attributes, 'n') != nullptr; |
113 | } |
114 | |
115 | /// Return true if we know this builtin never returns. |
116 | bool isNoReturn(unsigned ID) const { |
117 | return strchr(getRecord(ID).Attributes, 'r') != nullptr; |
118 | } |
119 | |
120 | /// Return true if we know this builtin can return twice. |
121 | bool isReturnsTwice(unsigned ID) const { |
122 | return strchr(getRecord(ID).Attributes, 'j') != nullptr; |
123 | } |
124 | |
125 | /// Returns true if this builtin does not perform the side-effects |
126 | /// of its arguments. |
127 | bool isUnevaluated(unsigned ID) const { |
128 | return strchr(getRecord(ID).Attributes, 'u') != nullptr; |
129 | } |
130 | |
131 | /// Return true if this is a builtin for a libc/libm function, |
132 | /// with a "__builtin_" prefix (e.g. __builtin_abs). |
133 | bool isLibFunction(unsigned ID) const { |
134 | return strchr(getRecord(ID).Attributes, 'F') != nullptr; |
135 | } |
136 | |
137 | /// Determines whether this builtin is a predefined libc/libm |
138 | /// function, such as "malloc", where we know the signature a |
139 | /// priori. |
140 | bool isPredefinedLibFunction(unsigned ID) const { |
141 | return strchr(getRecord(ID).Attributes, 'f') != nullptr; |
142 | } |
143 | |
144 | /// Returns true if this builtin requires appropriate header in other |
145 | /// compilers. In Clang it will work even without including it, but we can emit |
146 | /// a warning about missing header. |
147 | bool isHeaderDependentFunction(unsigned ID) const { |
148 | return strchr(getRecord(ID).Attributes, 'h') != nullptr; |
149 | } |
150 | |
151 | /// Determines whether this builtin is a predefined compiler-rt/libgcc |
152 | /// function, such as "__clear_cache", where we know the signature a |
153 | /// priori. |
154 | bool isPredefinedRuntimeFunction(unsigned ID) const { |
155 | return strchr(getRecord(ID).Attributes, 'i') != nullptr; |
156 | } |
157 | |
158 | /// Determines whether this builtin has custom typechecking. |
159 | bool hasCustomTypechecking(unsigned ID) const { |
160 | return strchr(getRecord(ID).Attributes, 't') != nullptr; |
161 | } |
162 | |
163 | /// Determines whether this builtin has a result or any arguments which |
164 | /// are pointer types. |
165 | bool hasPtrArgsOrResult(unsigned ID) const { |
166 | return strchr(getRecord(ID).Type, '*') != nullptr; |
167 | } |
168 | |
169 | /// Return true if this builtin has a result or any arguments which are |
170 | /// reference types. |
171 | bool hasReferenceArgsOrResult(unsigned ID) const { |
172 | return strchr(getRecord(ID).Type, '&') != nullptr || |
173 | strchr(getRecord(ID).Type, 'A') != nullptr; |
174 | } |
175 | |
176 | /// Completely forget that the given ID was ever considered a builtin, |
177 | /// e.g., because the user provided a conflicting signature. |
178 | void forgetBuiltin(unsigned ID, IdentifierTable &Table); |
179 | |
180 | /// If this is a library function that comes from a specific |
181 | /// header, retrieve that header name. |
182 | const char *getHeaderName(unsigned ID) const { |
183 | return getRecord(ID).HeaderName; |
184 | } |
185 | |
186 | /// Determine whether this builtin is like printf in its |
187 | /// formatting rules and, if so, set the index to the format string |
188 | /// argument and whether this function as a va_list argument. |
189 | bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg); |
190 | |
191 | /// Determine whether this builtin is like scanf in its |
192 | /// formatting rules and, if so, set the index to the format string |
193 | /// argument and whether this function as a va_list argument. |
194 | bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg); |
195 | |
196 | /// Determine whether this builtin has callback behavior (see |
197 | /// llvm::AbstractCallSites for details). If so, add the index to the |
198 | /// callback callee argument and the callback payload arguments. |
199 | bool performsCallback(unsigned ID, |
200 | llvm::SmallVectorImpl<int> &Encoding) const; |
201 | |
202 | /// Return true if this function has no side effects and doesn't |
203 | /// read memory, except for possibly errno. |
204 | /// |
205 | /// Such functions can be const when the MathErrno lang option is disabled. |
206 | bool isConstWithoutErrno(unsigned ID) const { |
207 | return strchr(getRecord(ID).Attributes, 'e') != nullptr; |
208 | } |
209 | |
210 | const char *getRequiredFeatures(unsigned ID) const { |
211 | return getRecord(ID).Features; |
212 | } |
213 | |
214 | unsigned getRequiredVectorWidth(unsigned ID) const; |
215 | |
216 | /// Return true if builtin ID belongs to AuxTarget. |
217 | bool isAuxBuiltinID(unsigned ID) const { |
218 | return ID >= (Builtin::FirstTSBuiltin + TSRecords.size()); |
219 | } |
220 | |
221 | /// Return real builtin ID (i.e. ID it would have during compilation |
222 | /// for AuxTarget). |
223 | unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); } |
224 | |
225 | /// Returns true if this is a libc/libm function without the '__builtin_' |
226 | /// prefix. |
227 | static bool isBuiltinFunc(const char *Name); |
228 | |
229 | /// Returns true if this is a builtin that can be redeclared. Returns true |
230 | /// for non-builtins. |
231 | bool canBeRedeclared(unsigned ID) const; |
232 | |
233 | private: |
234 | const Info &getRecord(unsigned ID) const; |
235 | |
236 | /// Is this builtin supported according to the given language options? |
237 | bool builtinIsSupported(const Builtin::Info &BuiltinInfo, |
238 | const LangOptions &LangOpts); |
239 | |
240 | /// Helper function for isPrintfLike and isScanfLike. |
241 | bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg, |
242 | const char *Fmt) const; |
243 | }; |
244 | |
245 | } |
246 | |
247 | /// Kinds of BuiltinTemplateDecl. |
248 | enum BuiltinTemplateKind : int { |
249 | /// This names the __make_integer_seq BuiltinTemplateDecl. |
250 | BTK__make_integer_seq, |
251 | |
252 | /// This names the __type_pack_element BuiltinTemplateDecl. |
253 | BTK__type_pack_element |
254 | }; |
255 | |
256 | } // end namespace clang |
257 | #endif |
258 |