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