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