diff options
author | Chris Lattner <sabre@nondot.org> | 2008-03-15 23:59:48 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-03-15 23:59:48 +0000 |
commit | bda0b626e74513950405c27525af87e214e605e2 (patch) | |
tree | 60149b18fd68ccc1281c62fe4387b5a1da39a5fa /lib/AST/Builtins.cpp | |
parent | fbdeba1c530dc3534a6f5b788e43d1a43c260128 (diff) |
Make a major restructuring of the clang tree: introduce a top-level
lib dir and move all the libraries into it. This follows the main
llvm tree, and allows the libraries to be built in parallel. The
top level now enforces that all the libs are built before Driver,
but we don't care what order the libs are built in. This speeds
up parallel builds, particularly incremental ones.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48402 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Builtins.cpp')
-rw-r--r-- | lib/AST/Builtins.cpp | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp new file mode 100644 index 0000000000..e2bf5ca007 --- /dev/null +++ b/lib/AST/Builtins.cpp @@ -0,0 +1,195 @@ +//===--- Builtins.cpp - Builtin function implementation -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements various things for builtin functions. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/Builtins.h" +#include "clang/AST/ASTContext.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/TargetInfo.h" +using namespace clang; + +static const Builtin::Info BuiltinInfo[] = { + { "not a builtin function", 0, 0 }, +#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS }, +#include "clang/AST/Builtins.def" +}; + +const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const { + if (ID < Builtin::FirstTSBuiltin) + return BuiltinInfo[ID]; + assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!"); + return TSRecords[ID - Builtin::FirstTSBuiltin]; +} + + +/// InitializeBuiltins - Mark the identifiers for all the builtins with their +/// appropriate builtin ID # and mark any non-portable builtin identifiers as +/// such. +void Builtin::Context::InitializeBuiltins(IdentifierTable &Table, + const TargetInfo &Target) { + // Step #1: mark all target-independent builtins with their ID's. + for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i) + Table.get(BuiltinInfo[i].Name).setBuiltinID(i); + + // Step #2: Get target builtins. + Target.getTargetBuiltins(TSRecords, NumTSRecords); + + // Step #3: Register target-specific builtins. + for (unsigned i = 0, e = NumTSRecords; i != e; ++i) + Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin); +} + +/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the +/// pointer over the consumed characters. This returns the resultant type. +static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context, + bool AllowTypeModifiers = true) { + // Modifiers. + bool Long = false, LongLong = false, Signed = false, Unsigned = false; + + // Read the modifiers first. + bool Done = false; + while (!Done) { + switch (*Str++) { + default: Done = true; --Str; break; + case 'S': + assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!"); + assert(!Signed && "Can't use 'S' modifier multiple times!"); + Signed = true; + break; + case 'U': + assert(!Signed && "Can't use both 'S' and 'U' modifiers!"); + assert(!Unsigned && "Can't use 'S' modifier multiple times!"); + Unsigned = true; + break; + case 'L': + assert(!LongLong && "Can't have LLL modifier"); + if (Long) + LongLong = true; + else + Long = true; + break; + } + } + + QualType Type; + + // Read the base type. + switch (*Str++) { + default: assert(0 && "Unknown builtin type letter!"); + case 'v': + assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'v'!"); + Type = Context.VoidTy; + break; + case 'f': + assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!"); + Type = Context.FloatTy; + break; + case 'd': + assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!"); + if (Long) + Type = Context.LongDoubleTy; + else + Type = Context.DoubleTy; + break; + case 's': + assert(!LongLong && "Bad modifiers used with 's'!"); + if (Unsigned) + Type = Context.UnsignedShortTy; + else + Type = Context.ShortTy; + break; + case 'i': + if (LongLong) + Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy; + else if (Long) + Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy; + else if (Unsigned) + Type = Context.UnsignedIntTy; + else + Type = Context.IntTy; // default is signed. + break; + case 'c': + assert(!Long && !LongLong && "Bad modifiers used with 'c'!"); + if (Signed) + Type = Context.SignedCharTy; + else if (Unsigned) + Type = Context.UnsignedCharTy; + else + Type = Context.CharTy; + break; + case 'z': // size_t. + assert(!Long && !Signed && !Unsigned && "Bad modifiers for 'z'!"); + Type = Context.getSizeType(); + break; + case 'F': + Type = Context.getCFConstantStringType(); + break; + case 'a': + Type = Context.getBuiltinVaListType(); + assert(!Type.isNull() && "builtin va list type not initialized!"); + break; + case 'V': { + char *End; + + unsigned NumElements = strtoul(Str, &End, 10); + assert(End != Str && "Missing vector size"); + + Str = End; + + QualType ElementType = DecodeTypeFromStr(Str, Context, false); + Type = Context.getVectorType(ElementType, NumElements); + break; + } + } + + if (!AllowTypeModifiers) + return Type; + + Done = false; + while (!Done) { + switch (*Str++) { + default: Done = true; --Str; break; + case '*': + Type = Context.getPointerType(Type); + break; + case '&': + Type = Context.getReferenceType(Type); + break; + case 'C': + Type = Type.getQualifiedType(QualType::Const); + break; + } + } + + return Type; +} + +/// GetBuiltinType - Return the type for the specified builtin. +QualType Builtin::Context::GetBuiltinType(unsigned id, + ASTContext &Context) const { + const char *TypeStr = GetRecord(id).Type; + + llvm::SmallVector<QualType, 8> ArgTypes; + + QualType ResType = DecodeTypeFromStr(TypeStr, Context); + while (TypeStr[0] && TypeStr[0] != '.') + ArgTypes.push_back(DecodeTypeFromStr(TypeStr, Context)); + + assert((TypeStr[0] != '.' || TypeStr[1] == 0) && + "'.' should only occur at end of builtin type list!"); + + // handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);". + if (ArgTypes.size() == 0 && TypeStr[0] == '.') + return Context.getFunctionTypeNoProto(ResType); + return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(), + TypeStr[0] == '.'); +} |