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 LangOptions; 29 30 enum LanguageID { 31 GNU_LANG = 0x1, // builtin requires GNU mode. 32 C_LANG = 0x2, // builtin for c only. 33 CXX_LANG = 0x4, // builtin for cplusplus only. 34 OBJC_LANG = 0x8, // builtin for objective-c and objective-c++ 35 MS_LANG = 0x10, // builtin requires MS mode. 36 OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only. 37 OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only. 38 OMP_LANG = 0x80, // builtin requires OpenMP. 39 CUDA_LANG = 0x100, // builtin requires CUDA. 40 COR_LANG = 0x200, // builtin requires use of 'fcoroutine-ts' option. 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: Context()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". getName(unsigned ID)85 const char *getName(unsigned ID) const { 86 return getRecord(ID).Name; 87 } 88 89 /// Get the type descriptor string for the specified builtin. getTypeString(unsigned ID)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. isTSBuiltin(unsigned ID)95 bool isTSBuiltin(unsigned ID) const { 96 return ID >= Builtin::FirstTSBuiltin; 97 } 98 99 /// Return true if this function has no side effects. isPure(unsigned ID)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. isConst(unsigned ID)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. isNoThrow(unsigned ID)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. isNoReturn(unsigned ID)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. isReturnsTwice(unsigned ID)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. isUnevaluated(unsigned ID)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). isLibFunction(unsigned ID)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. isPredefinedLibFunction(unsigned ID)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. isHeaderDependentFunction(unsigned ID)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. isPredefinedRuntimeFunction(unsigned ID)154 bool isPredefinedRuntimeFunction(unsigned ID) const { 155 return strchr(getRecord(ID).Attributes, 'i') != nullptr; 156 } 157 158 /// Determines whether this builtin has custom typechecking. hasCustomTypechecking(unsigned ID)159 bool hasCustomTypechecking(unsigned ID) const { 160 return strchr(getRecord(ID).Attributes, 't') != nullptr; 161 } 162 163 /// Determines whether a declaration of this builtin should be recognized 164 /// even if the type doesn't match the specified signature. allowTypeMismatch(unsigned ID)165 bool allowTypeMismatch(unsigned ID) const { 166 return strchr(getRecord(ID).Attributes, 'T') != nullptr || 167 hasCustomTypechecking(ID); 168 } 169 170 /// Determines whether this builtin has a result or any arguments which 171 /// are pointer types. hasPtrArgsOrResult(unsigned ID)172 bool hasPtrArgsOrResult(unsigned ID) const { 173 return strchr(getRecord(ID).Type, '*') != nullptr; 174 } 175 176 /// Return true if this builtin has a result or any arguments which are 177 /// reference types. hasReferenceArgsOrResult(unsigned ID)178 bool hasReferenceArgsOrResult(unsigned ID) const { 179 return strchr(getRecord(ID).Type, '&') != nullptr || 180 strchr(getRecord(ID).Type, 'A') != nullptr; 181 } 182 183 /// If this is a library function that comes from a specific 184 /// header, retrieve that header name. getHeaderName(unsigned ID)185 const char *getHeaderName(unsigned ID) const { 186 return getRecord(ID).HeaderName; 187 } 188 189 /// Determine whether this builtin is like printf in its 190 /// formatting rules and, if so, set the index to the format string 191 /// argument and whether this function as a va_list argument. 192 bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg); 193 194 /// Determine whether this builtin is like scanf in its 195 /// formatting rules and, if so, set the index to the format string 196 /// argument and whether this function as a va_list argument. 197 bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg); 198 199 /// Determine whether this builtin has callback behavior (see 200 /// llvm::AbstractCallSites for details). If so, add the index to the 201 /// callback callee argument and the callback payload arguments. 202 bool performsCallback(unsigned ID, 203 llvm::SmallVectorImpl<int> &Encoding) const; 204 205 /// Return true if this function has no side effects and doesn't 206 /// read memory, except for possibly errno. 207 /// 208 /// Such functions can be const when the MathErrno lang option is disabled. isConstWithoutErrno(unsigned ID)209 bool isConstWithoutErrno(unsigned ID) const { 210 return strchr(getRecord(ID).Attributes, 'e') != nullptr; 211 } 212 getRequiredFeatures(unsigned ID)213 const char *getRequiredFeatures(unsigned ID) const { 214 return getRecord(ID).Features; 215 } 216 217 unsigned getRequiredVectorWidth(unsigned ID) const; 218 219 /// Return true if builtin ID belongs to AuxTarget. isAuxBuiltinID(unsigned ID)220 bool isAuxBuiltinID(unsigned ID) const { 221 return ID >= (Builtin::FirstTSBuiltin + TSRecords.size()); 222 } 223 224 /// Return real builtin ID (i.e. ID it would have during compilation 225 /// for AuxTarget). getAuxBuiltinID(unsigned ID)226 unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); } 227 228 /// Returns true if this is a libc/libm function without the '__builtin_' 229 /// prefix. 230 static bool isBuiltinFunc(llvm::StringRef Name); 231 232 /// Returns true if this is a builtin that can be redeclared. Returns true 233 /// for non-builtins. 234 bool canBeRedeclared(unsigned ID) const; 235 236 private: 237 const Info &getRecord(unsigned ID) const; 238 239 /// Is this builtin supported according to the given language options? 240 bool builtinIsSupported(const Builtin::Info &BuiltinInfo, 241 const LangOptions &LangOpts); 242 243 /// Helper function for isPrintfLike and isScanfLike. 244 bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg, 245 const char *Fmt) const; 246 }; 247 248 } 249 250 /// Kinds of BuiltinTemplateDecl. 251 enum BuiltinTemplateKind : int { 252 /// This names the __make_integer_seq BuiltinTemplateDecl. 253 BTK__make_integer_seq, 254 255 /// This names the __type_pack_element BuiltinTemplateDecl. 256 BTK__type_pack_element 257 }; 258 259 } // end namespace clang 260 #endif 261