blob: af5056206625ceb7e0349a24089f175df486c6ec [file] [log] [blame]
Chris Lattner9561a0b2007-01-28 08:20:04 +00001//===--- Builtins.cpp - Builtin function implementation -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements various things for builtin functions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/Builtins.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/Lex/IdentifierTable.h"
Chris Lattner10a5b382007-01-29 05:24:35 +000017#include "clang/Basic/TargetInfo.h"
Chris Lattner9561a0b2007-01-28 08:20:04 +000018using namespace llvm;
19using namespace clang;
20
21static const Builtin::Info BuiltinInfo[] = {
22 { "not a builtin function", 0, 0 },
23#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
24#include "clang/AST/Builtins.def"
25};
26
Chris Lattner10a5b382007-01-29 05:24:35 +000027const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
28 if (ID < Builtin::FirstTSBuiltin)
29 return BuiltinInfo[ID];
30 assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!");
31 return TSRecords[ID - Builtin::FirstTSBuiltin];
Chris Lattner9561a0b2007-01-28 08:20:04 +000032}
33
34
35/// InitializeBuiltins - Mark the identifiers for all the builtins with their
36/// appropriate builtin ID # and mark any non-portable builtin identifiers as
37/// such.
Chris Lattner10a5b382007-01-29 05:24:35 +000038void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
39 const TargetInfo &Target) {
Chris Lattner9561a0b2007-01-28 08:20:04 +000040 // Step #1: mark all target-independent builtins with their ID's.
Chris Lattner10a5b382007-01-29 05:24:35 +000041 for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
Chris Lattner9561a0b2007-01-28 08:20:04 +000042 Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
43
44 // Step #2: handle target builtins.
Chris Lattner10a5b382007-01-29 05:24:35 +000045 std::vector<const char *> NonPortableBuiltins;
46 Target.getTargetBuiltins(TSRecords, NumTSRecords, NonPortableBuiltins);
47
48 // Step #2a: Register target-specific builtins.
49 for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
50 Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
51
52 // Step #2b: Mark non-portable builtins as such.
53 for (unsigned i = 0, e = NonPortableBuiltins.size(); i != e; ++i)
54 Table.get(NonPortableBuiltins[i]).setNonPortableBuiltin(true);
Chris Lattner9561a0b2007-01-28 08:20:04 +000055}
56
57/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
58/// pointer over the consumed characters. This returns the resultant type.
Steve Naroffe5aa9be2007-04-05 22:36:20 +000059static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context) {
Chris Lattner9561a0b2007-01-28 08:20:04 +000060 // Modifiers.
61 bool Long = false, LongLong = false, Signed = false, Unsigned = false;
62
63 // Read the modifiers first.
64 bool Done = false;
65 while (!Done) {
66 switch (*Str++) {
67 default: Done = true; --Str; break;
68 case 'S':
69 assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");
70 assert(!Signed && "Can't use 'S' modifier multiple times!");
71 Signed = true;
72 break;
73 case 'U':
74 assert(!Signed && "Can't use both 'S' and 'U' modifiers!");
75 assert(!Unsigned && "Can't use 'S' modifier multiple times!");
76 Unsigned = true;
77 break;
78 case 'L':
79 assert(!LongLong && "Can't have LLL modifier");
80 if (Long)
81 LongLong = true;
82 else
83 Long = true;
84 break;
85 }
86 }
87
88 // Read the base type.
89 switch (*Str++) {
90 default: assert(0 && "Unknown builtin type letter!");
Chris Lattner10a5b382007-01-29 05:24:35 +000091 case 'v':
92 assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
93 return Context.VoidTy;
Chris Lattner9561a0b2007-01-28 08:20:04 +000094 case 'f':
95 assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
96 return Context.FloatTy;
97 case 'd':
98 assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!");
99 if (Long)
100 return Context.LongDoubleTy;
101 return Context.DoubleTy;
Steve Naroff97035852007-03-16 01:36:44 +0000102 case 's':
103 assert(!LongLong && "Bad modifiers used with 's'!");
104 if (Unsigned)
105 return Context.UnsignedShortTy;
106 return Context.ShortTy;
Chris Lattner9561a0b2007-01-28 08:20:04 +0000107 //case 'i':
108 }
109}
110
111/// GetBuiltinType - Return the type for the specified builtin.
Steve Naroffe5aa9be2007-04-05 22:36:20 +0000112QualType Builtin::Context::GetBuiltinType(unsigned id, ASTContext &Context)const{
Chris Lattner10a5b382007-01-29 05:24:35 +0000113 const char *TypeStr = GetRecord(id).Type;
Chris Lattner9561a0b2007-01-28 08:20:04 +0000114
Steve Naroffe5aa9be2007-04-05 22:36:20 +0000115 SmallVector<QualType, 8> ArgTypes;
Chris Lattner9561a0b2007-01-28 08:20:04 +0000116
Steve Naroffe5aa9be2007-04-05 22:36:20 +0000117 QualType ResType = DecodeTypeFromStr(TypeStr, Context);
Chris Lattner9561a0b2007-01-28 08:20:04 +0000118 while (TypeStr[0] && TypeStr[0] != '.')
119 ArgTypes.push_back(DecodeTypeFromStr(TypeStr, Context));
120
121 assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
122 "'.' should only occur at end of builtin type list!");
123
124 return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(),
125 TypeStr[0] == '.');
126}