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