Builtins.cpp revision a316e7b735b12ce6b34961a9dcfaae34f4b08d29
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Builtins.cpp - Builtin function implementation -------------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements various things for builtin functions. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/Builtins.h" 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/ASTContext.h" 16e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "clang/AST/Decl.h" 17c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/IdentifierTable.h" 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TargetInfo.h" 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic const Builtin::Info BuiltinInfo[] = { 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer { "not a builtin function", 0, 0 }, 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS }, 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/Builtins.def" 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const { 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ID < Builtin::FirstTSBuiltin) 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return BuiltinInfo[ID]; 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!"); 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return TSRecords[ID - Builtin::FirstTSBuiltin]; 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// InitializeBuiltins - Mark the identifiers for all the builtins with their 365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// appropriate builtin ID # and mark any non-portable builtin identifiers as 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// such. 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid Builtin::Context::InitializeBuiltins(IdentifierTable &Table, 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const TargetInfo &Target) { 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Step #1: mark all target-independent builtins with their ID's. 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i) 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Table.get(BuiltinInfo[i].Name).setBuiltinID(i); 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4442e6737f2efb113563140ad794c21c7709250402Chris Lattner // Step #2: Get target builtins. 4542e6737f2efb113563140ad794c21c7709250402Chris Lattner Target.getTargetBuiltins(TSRecords, NumTSRecords); 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4742e6737f2efb113563140ad794c21c7709250402Chris Lattner // Step #3: Register target-specific builtins. 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (unsigned i = 0, e = NumTSRecords; i != e; ++i) 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin); 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 52a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregorstd::string Builtin::Context::getHeaderName(unsigned ID) const { 53a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor char *Name = strchr(GetRecord(ID).Attributes, 'f'); 54a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor if (!Name) 55a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor return 0; 56a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor ++Name; 57a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 58a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor if (*Name != ':') 59a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor return 0; 60a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 61a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor ++Name; 62a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor char *NameEnd = strchr(Name, ':'); 63a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor assert(NameEnd && "Missing ':' after header name"); 64a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor return std::string(Name, NameEnd); 65a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor} 66a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 67a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregorbool 68a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas GregorBuiltin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx, 69a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor bool &HasVAListArg) { 70a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor char *Printf = strpbrk(GetRecord(ID).Attributes, "pP"); 71a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor if (!Printf) 72a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor return false; 73a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 74a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor HasVAListArg = (*Printf == 'P'); 75a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 76a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor ++Printf; 77a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor assert(*Printf == ':' && "p or P specifier must have be followed by a ':'"); 78a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor ++Printf; 79a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 80a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor char *PrintfEnd = strchr(Printf, ':'); 81a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor assert(PrintfEnd && "printf specifier must end with a ':'"); 82a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 83a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor FormatIdx = strtol(Printf, 0, 10); 84a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor return true; 85a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor} 86a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor 875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// pointer over the consumed characters. This returns the resultant type. 89dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlssonstatic QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context, 90dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlsson bool AllowTypeModifiers = true) { 915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Modifiers. 925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool Long = false, LongLong = false, Signed = false, Unsigned = false; 935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the modifiers first. 955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool Done = false; 965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer while (!Done) { 975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (*Str++) { 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: Done = true; --Str; break; 995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case 'S': 1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!"); 1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!Signed && "Can't use 'S' modifier multiple times!"); 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Signed = true; 1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case 'U': 1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!Signed && "Can't use both 'S' and 'U' modifiers!"); 1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!Unsigned && "Can't use 'S' modifier multiple times!"); 1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Unsigned = true; 1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case 'L': 1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!LongLong && "Can't have LLL modifier"); 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (Long) 1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer LongLong = true; 1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer else 1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Long = true; 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 11971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson QualType Type; 12071993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson 1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the base type. 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (*Str++) { 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown builtin type letter!"); 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case 'v': 125e8770421d8463db203b78eb96f93a75ea5e58346Steve Naroff assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'v'!"); 12671993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.VoidTy; 12771993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case 'f': 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!"); 13071993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.FloatTy; 13171993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case 'd': 1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!"); 1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (Long) 13571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.LongDoubleTy; 13671993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson else 13771993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.DoubleTy; 13871993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case 's': 1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!LongLong && "Bad modifiers used with 's'!"); 1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (Unsigned) 14271993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.UnsignedShortTy; 14371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson else 14471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.ShortTy; 14571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 146e8770421d8463db203b78eb96f93a75ea5e58346Steve Naroff case 'i': 147142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson if (LongLong) 14871993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy; 149142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson else if (Long) 150142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy; 15171993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson else if (Unsigned) 15271993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.UnsignedIntTy; 15371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson else 15471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.IntTy; // default is signed. 15571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 15671993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson case 'c': 15771993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson assert(!Long && !LongLong && "Bad modifiers used with 'c'!"); 15871993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson if (Signed) 15971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.SignedCharTy; 16071993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson else if (Unsigned) 16171993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.UnsignedCharTy; 16271993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson else 16371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.CharTy; 16471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 1657ae48ee2fb80b0a3ac6ad912b465a077c7591a19Mon P Wang case 'b': // boolean 1667ae48ee2fb80b0a3ac6ad912b465a077c7591a19Mon P Wang assert(!Long && !Signed && !Unsigned && "Bad modifiers for 'b'!"); 1677ae48ee2fb80b0a3ac6ad912b465a077c7591a19Mon P Wang Type = Context.BoolTy; 1687ae48ee2fb80b0a3ac6ad912b465a077c7591a19Mon P Wang break; 16952735a0339dd31750251a13aac73677693410c9dChris Lattner case 'z': // size_t. 17052735a0339dd31750251a13aac73677693410c9dChris Lattner assert(!Long && !Signed && !Unsigned && "Bad modifiers for 'z'!"); 17152735a0339dd31750251a13aac73677693410c9dChris Lattner Type = Context.getSizeType(); 17252735a0339dd31750251a13aac73677693410c9dChris Lattner break; 17371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson case 'F': 17471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.getCFConstantStringType(); 17571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 176142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson case 'a': 177b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson Type = Context.getBuiltinVaListType(); 178793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson assert(!Type.isNull() && "builtin va list type not initialized!"); 179b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson break; 1806597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman case 'A': 1816597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // This is a "reference" to a va_list; however, what exactly 1826597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // this means depends on how va_list is defined. There are two 1836597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // different kinds of va_list: ones passed by value, and ones 1846597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // passed by reference. An example of a by-value va_list is 1856597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // x86, where va_list is a char*. An example of by-ref va_list 1866597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // is x86-64, where va_list is a __va_list_tag[1]. For x86, 1876597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // we want this argument to be a char*&; for x86-64, we want 1886597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman // it to be a __va_list_tag*. 1896597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman Type = Context.getBuiltinVaListType(); 1906597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman assert(!Type.isNull() && "builtin va list type not initialized!"); 1916597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman if (Type->isArrayType()) { 1926597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman Type = Context.getArrayDecayedType(Type); 1936597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman } else { 1946597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman Type = Context.getReferenceType(Type); 1956597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman } 1966597f985156b3a24c0a9db1e01eeec85714c4a8dEli Friedman break; 197142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson case 'V': { 198142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson char *End; 199142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson 200142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson unsigned NumElements = strtoul(Str, &End, 10); 201142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson assert(End != Str && "Missing vector size"); 202142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson 203142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson Str = End; 204142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson 205dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlsson QualType ElementType = DecodeTypeFromStr(Str, Context, false); 206142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson Type = Context.getVectorType(ElementType, NumElements); 207142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson break; 208142f36de332925dbe19d73d0612d9879b4f80e84Anders Carlsson } 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 21071993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson 211dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlsson if (!AllowTypeModifiers) 212dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlsson return Type; 213dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlsson 21471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Done = false; 21571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson while (!Done) { 21671993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson switch (*Str++) { 217dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlsson default: Done = true; --Str; break; 21871993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson case '*': 21971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Context.getPointerType(Type); 22071993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 221793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case '&': 222793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson Type = Context.getReferenceType(Type); 223793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson break; 22471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson case 'C': 22571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson Type = Type.getQualifiedType(QualType::Const); 22671993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson break; 22771993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson } 22871993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson } 22971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson 23071993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson return Type; 2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// GetBuiltinType - Return the type for the specified builtin. 23422b73ba6c6bbac2b117f7e27d53ea683ede14c68Chris LattnerQualType Builtin::Context::GetBuiltinType(unsigned id, 23522b73ba6c6bbac2b117f7e27d53ea683ede14c68Chris Lattner ASTContext &Context) const { 2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *TypeStr = GetRecord(id).Type; 2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::SmallVector<QualType, 8> ArgTypes; 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer QualType ResType = DecodeTypeFromStr(TypeStr, Context); 241f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner while (TypeStr[0] && TypeStr[0] != '.') { 242f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner QualType Ty = DecodeTypeFromStr(TypeStr, Context); 243f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner 244f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner // Do array -> pointer decay. The builtin should use the decayed type. 245f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner if (Ty->isArrayType()) 246f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner Ty = Context.getArrayDecayedType(Ty); 247f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner 248f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner ArgTypes.push_back(Ty); 249f77d545fe923d4c465fb07476254798135a8ed25Chris Lattner } 250dd1b516f2f5ed5953de1875afc2d04aa5a14d137Anders Carlsson 2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert((TypeStr[0] != '.' || TypeStr[1] == 0) && 2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer "'.' should only occur at end of builtin type list!"); 253e8770421d8463db203b78eb96f93a75ea5e58346Steve Naroff 254e8770421d8463db203b78eb96f93a75ea5e58346Steve Naroff // handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);". 255e8770421d8463db203b78eb96f93a75ea5e58346Steve Naroff if (ArgTypes.size() == 0 && TypeStr[0] == '.') 256e8770421d8463db203b78eb96f93a75ea5e58346Steve Naroff return Context.getFunctionTypeNoProto(ResType); 2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(), 2587fb5e4888221cd36652d078c6b171ac55e7f406dArgyrios Kyrtzidis TypeStr[0] == '.', 0); 2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 260