diff options
| author | Chris Lattner <sabre@nondot.org> | 2007-01-29 05:24:35 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2007-01-29 05:24:35 +0000 |
| commit | 10a5b387cc5c4856356b7a3354f053895a275d01 (patch) | |
| tree | ec4720cee869c1a1bccdac8c5f288a7f52ca3bd5 | |
| parent | 9561a0b3e7d65522086d703c170e6b0e41edf02a (diff) | |
| download | bcm5719-llvm-10a5b387cc5c4856356b7a3354f053895a275d01.tar.gz bcm5719-llvm-10a5b387cc5c4856356b7a3354f053895a275d01.zip | |
Add support for target-specific builtins, including detecting nonportability
of source code. For example:
$ clang INPUTS/carbon_h.c -arch i386 -arch ppc
prints:
...
/usr/lib/gcc/i686-apple-darwin8/4.0.1/include/mmintrin.h:51:3: note: use of a target-specific builtin function, source is not 'portable'
__builtin_ia32_emms ();
^
because carbon.h pulls in xmmintrin.h, and __builtin_ia32_emms isn't a builtin on ppc.
Though clang now supports target-specific builtins, the full table isn't implemented yet.
llvm-svn: 39328
| -rw-r--r-- | clang/AST/ASTContext.cpp | 3 | ||||
| -rw-r--r-- | clang/AST/Builtins.cpp | 39 | ||||
| -rw-r--r-- | clang/AST/SemaDecl.cpp | 2 | ||||
| -rw-r--r-- | clang/Basic/TargetInfo.cpp | 56 | ||||
| -rw-r--r-- | clang/Driver/PPCBuiltins.def | 24 | ||||
| -rw-r--r-- | clang/Driver/Targets.cpp | 62 | ||||
| -rw-r--r-- | clang/Driver/X86Builtins.def | 23 | ||||
| -rw-r--r-- | clang/Sema/SemaDecl.cpp | 2 | ||||
| -rw-r--r-- | clang/clang.xcodeproj/project.pbxproj | 8 | ||||
| -rw-r--r-- | clang/include/clang/AST/ASTContext.h | 2 | ||||
| -rw-r--r-- | clang/include/clang/AST/Builtins.h | 46 | ||||
| -rw-r--r-- | clang/include/clang/Basic/TargetInfo.h | 14 |
12 files changed, 250 insertions, 31 deletions
diff --git a/clang/AST/ASTContext.cpp b/clang/AST/ASTContext.cpp index 0abaf666dec..1edfde15638 100644 --- a/clang/AST/ASTContext.cpp +++ b/clang/AST/ASTContext.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" -#include "clang/AST/Builtins.h" #include "clang/AST/Decl.h" #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/SmallVector.h" @@ -22,7 +21,7 @@ using namespace clang; ASTContext::ASTContext(Preprocessor &pp) : PP(pp), Target(pp.getTargetInfo()) { InitBuiltinTypes(); - Builtin::InitializeBuiltins(PP.getIdentifierTable(), Target); + BuiltinInfo.InitializeBuiltins(PP.getIdentifierTable(), Target); } ASTContext::~ASTContext() { diff --git a/clang/AST/Builtins.cpp b/clang/AST/Builtins.cpp index e5ff8fbe83d..5815c80e99a 100644 --- a/clang/AST/Builtins.cpp +++ b/clang/AST/Builtins.cpp @@ -14,6 +14,7 @@ #include "clang/AST/Builtins.h" #include "clang/AST/ASTContext.h" #include "clang/Lex/IdentifierTable.h" +#include "clang/Basic/TargetInfo.h" using namespace llvm; using namespace clang; @@ -23,27 +24,34 @@ static const Builtin::Info BuiltinInfo[] = { #include "clang/AST/Builtins.def" }; -/// Builtin::GetName - Return the identifier name for the specified builtin, -/// e.g. "__builtin_abs". -const char *Builtin::GetName(ID id) { - if (id >= Builtin::FirstTargetSpecificBuiltin) - return "target-builtin"; - return BuiltinInfo[id].Name; +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::InitializeBuiltins(IdentifierTable &Table, - const TargetInfo &Target) { +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::FirstTargetSpecificBuiltin; ++i) + for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i) Table.get(BuiltinInfo[i].Name).setBuiltinID(i); // Step #2: handle target builtins. - // FIXME: implement. + std::vector<const char *> NonPortableBuiltins; + Target.getTargetBuiltins(TSRecords, NumTSRecords, NonPortableBuiltins); + + // Step #2a: Register target-specific builtins. + for (unsigned i = 0, e = NumTSRecords; i != e; ++i) + Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin); + + // Step #2b: Mark non-portable builtins as such. + for (unsigned i = 0, e = NonPortableBuiltins.size(); i != e; ++i) + Table.get(NonPortableBuiltins[i]).setNonPortableBuiltin(true); } /// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the @@ -80,6 +88,9 @@ static TypeRef DecodeTypeFromStr(const char *&Str, ASTContext &Context) { // Read the base type. switch (*Str++) { default: assert(0 && "Unknown builtin type letter!"); + case 'v': + assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!"); + return Context.VoidTy; case 'f': assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!"); return Context.FloatTy; @@ -93,10 +104,8 @@ static TypeRef DecodeTypeFromStr(const char *&Str, ASTContext &Context) { } /// GetBuiltinType - Return the type for the specified builtin. -TypeRef Builtin::GetBuiltinType(ID id, ASTContext &Context) { - assert(id < Builtin::FirstTargetSpecificBuiltin && - "Can't handle target builtins yet!"); - const char *TypeStr = BuiltinInfo[id].Type; +TypeRef Builtin::Context::GetBuiltinType(unsigned id, ASTContext &Context)const{ + const char *TypeStr = GetRecord(id).Type; SmallVector<TypeRef, 8> ArgTypes; diff --git a/clang/AST/SemaDecl.cpp b/clang/AST/SemaDecl.cpp index 0d7e865ad2d..e339f167e3f 100644 --- a/clang/AST/SemaDecl.cpp +++ b/clang/AST/SemaDecl.cpp @@ -109,7 +109,7 @@ Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI, Decl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Scope *S) { Builtin::ID BID = (Builtin::ID)bid; - TypeRef R = Builtin::GetBuiltinType(BID, Context); + TypeRef R = Context.BuiltinInfo.GetBuiltinType(BID, Context); FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R); // Find translation-unit scope to insert this function into. diff --git a/clang/Basic/TargetInfo.cpp b/clang/Basic/TargetInfo.cpp index 21925fd33e9..3dd9488e315 100644 --- a/clang/Basic/TargetInfo.cpp +++ b/clang/Basic/TargetInfo.cpp @@ -13,7 +13,9 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Diagnostic.h" +#include "clang/AST/Builtins.h" #include <map> +#include <set> using namespace llvm; using namespace clang; @@ -148,3 +150,57 @@ void TargetInfo::ComputeWCharWidth(SourceLocation Loc) { return DiagnoseNonPortability(Loc, diag::port_wchar_t); } + +/// getTargetBuiltins - Return information about target-specific builtins for +/// the current primary target, and info about which builtins are non-portable +/// across the current set of primary and secondary targets. +void TargetInfo::getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords, + std::vector<const char *> &NPortable) const { + // Get info about what actual builtins we will expose. + PrimaryTarget->getTargetBuiltins(Records, NumRecords); + if (SecondaryTargets.empty()) return; + + // Compute the set of non-portable builtins. + + // Start by computing a mapping from the primary target's builtins to their + // info records for efficient lookup. + std::map<std::string, const Builtin::Info*> PrimaryRecs; + for (unsigned i = 0, e = NumRecords; i != e; ++i) + PrimaryRecs[Records[i].Name] = Records+i; + + for (unsigned i = 0, e = SecondaryTargets.size(); i != e; ++i) { + // Get the builtins for this secondary target. + const Builtin::Info *Records2nd; + unsigned NumRecords2nd; + SecondaryTargets[i]->getTargetBuiltins(Records2nd, NumRecords2nd); + + // Remember all of the secondary builtin names. + std::set<std::string> BuiltinNames2nd; + + for (unsigned j = 0, e = NumRecords2nd; j != e; ++j) { + BuiltinNames2nd.insert(Records2nd[j].Name); + + // Check to see if the primary target has this builtin. + if (const Builtin::Info *PrimBI = PrimaryRecs[Records2nd[j].Name]) { + // If does. If they are not identical, mark the builtin as being + // non-portable. + if (Records2nd[j] != *PrimBI) + NPortable.push_back(PrimBI->Name); + } else { + // The primary target doesn't have this, it is non-portable. + NPortable.push_back(Records2nd[j].Name); + } + } + + // Now that we checked all the secondary builtins, check to see if the + // primary target has any builtins that the secondary one doesn't. If so, + // then those are non-portable. + for (unsigned j = 0, e = NumRecords; j != e; ++j) { + if (!BuiltinNames2nd.count(Records[j].Name)) + NPortable.push_back(Records[j].Name); + } + } +} + + diff --git a/clang/Driver/PPCBuiltins.def b/clang/Driver/PPCBuiltins.def new file mode 100644 index 00000000000..6aed2caa4d7 --- /dev/null +++ b/clang/Driver/PPCBuiltins.def @@ -0,0 +1,24 @@ +//===--- PPCBuiltins.def - PowerPC Builtin function database ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PowerPC-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +// FIXME: this needs to be the full list supported by GCC. Right now, I'm just +// adding stuff on demand. + +// The format of this database matches clang/AST/Builtins.def. + +// This is just a placeholder, the types and attributes are wrong. +BUILTIN(__builtin_altivec_abs_v4sf , "ii" , "nc") +// FIXME: Obviously incomplete. + +#undef BUILTIN diff --git a/clang/Driver/Targets.cpp b/clang/Driver/Targets.cpp index 822579018d1..a84780761e3 100644 --- a/clang/Driver/Targets.cpp +++ b/clang/Driver/Targets.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang.h" +#include "clang/AST/Builtins.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "llvm/Support/CommandLine.h" @@ -270,6 +271,47 @@ static void getX86Defines(std::vector<std::string> &Defines, bool is64Bit) { } +/// PPC builtin info. +namespace PPC { + enum { + LastTIBuiltin = Builtin::FirstTSBuiltin-1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "PPCBuiltins.def" + LastTSBuiltin + }; + + static const Builtin::Info BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS }, +#include "PPCBuiltins.def" + }; + + static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) { + Records = BuiltinInfo; + NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin; + } +} // End namespace PPC + + +/// X86 builtin info. +namespace X86 { + enum { + LastTIBuiltin = Builtin::FirstTSBuiltin-1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "X86Builtins.def" + LastTSBuiltin + }; + + static const Builtin::Info BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS }, +#include "X86Builtins.def" + }; + + static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) { + Records = BuiltinInfo; + NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin; + } +} // End namespace X86 + //===----------------------------------------------------------------------===// // Specific target implementations. //===----------------------------------------------------------------------===// @@ -282,6 +324,10 @@ public: DarwinTargetInfo::getTargetDefines(Defines); getPowerPCDefines(Defines, false); } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + PPC::getBuiltins(Records, NumRecords); + } }; } // end anonymous namespace. @@ -292,6 +338,10 @@ public: DarwinTargetInfo::getTargetDefines(Defines); getPowerPCDefines(Defines, true); } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + PPC::getBuiltins(Records, NumRecords); + } }; } // end anonymous namespace. @@ -302,6 +352,10 @@ public: DarwinTargetInfo::getTargetDefines(Defines); getX86Defines(Defines, false); } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + X86::getBuiltins(Records, NumRecords); + } }; } // end anonymous namespace. @@ -312,6 +366,10 @@ public: DarwinTargetInfo::getTargetDefines(Defines); getX86Defines(Defines, true); } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + X86::getBuiltins(Records, NumRecords); + } }; } // end anonymous namespace. @@ -327,6 +385,10 @@ public: // TODO: linux-specific stuff. getX86Defines(Defines, false); } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + X86::getBuiltins(Records, NumRecords); + } }; } // end anonymous namespace. diff --git a/clang/Driver/X86Builtins.def b/clang/Driver/X86Builtins.def new file mode 100644 index 00000000000..ef2d7920b7a --- /dev/null +++ b/clang/Driver/X86Builtins.def @@ -0,0 +1,23 @@ +//===--- X86Builtins.def - X86 Builtin function database --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the X86-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +// FIXME: this needs to be the full list supported by GCC. Right now, I'm just +// adding stuff on demand. + +// The format of this database matches clang/AST/Builtins.def. + +BUILTIN(__builtin_ia32_emms , "v" , "") +// FIXME: Obviously incomplete. + +#undef BUILTIN diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index 0d7e865ad2d..e339f167e3f 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/Sema/SemaDecl.cpp @@ -109,7 +109,7 @@ Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI, Decl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Scope *S) { Builtin::ID BID = (Builtin::ID)bid; - TypeRef R = Builtin::GetBuiltinType(BID, Context); + TypeRef R = Context.BuiltinInfo.GetBuiltinType(BID, Context); FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R); // Find translation-unit scope to insert this function into. diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index 50f3b96ebcf..6b0daecd9b3 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -60,6 +60,8 @@ DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676D00B6C786700AAD4A3 /* Builtins.def */; }; DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676F90B6C797B00AAD4A3 /* Builtins.h */; }; DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED677C80B6C854100AAD4A3 /* Builtins.cpp */; }; + DED67AEE0B6DB92A00AAD4A3 /* X86Builtins.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED67AED0B6DB92A00AAD4A3 /* X86Builtins.def */; }; + DED67AF00B6DB92F00AAD4A3 /* PPCBuiltins.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED67AEF0B6DB92F00AAD4A3 /* PPCBuiltins.def */; }; DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7310A524295003AD0FB /* Diagnostic.h */; }; DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7320A524295003AD0FB /* DiagnosticKinds.def */; }; DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; }; @@ -139,6 +141,8 @@ DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */, DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */, DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */, + DED67AEE0B6DB92A00AAD4A3 /* X86Builtins.def in CopyFiles */, + DED67AF00B6DB92F00AAD4A3 /* PPCBuiltins.def in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; @@ -199,6 +203,8 @@ DED676D00B6C786700AAD4A3 /* Builtins.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = Builtins.def; path = clang/AST/Builtins.def; sourceTree = "<group>"; }; DED676F90B6C797B00AAD4A3 /* Builtins.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Builtins.h; path = clang/AST/Builtins.h; sourceTree = "<group>"; }; DED677C80B6C854100AAD4A3 /* Builtins.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Builtins.cpp; path = AST/Builtins.cpp; sourceTree = "<group>"; }; + DED67AED0B6DB92A00AAD4A3 /* X86Builtins.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = X86Builtins.def; path = Driver/X86Builtins.def; sourceTree = "<group>"; }; + DED67AEF0B6DB92F00AAD4A3 /* PPCBuiltins.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCBuiltins.def; path = Driver/PPCBuiltins.def; sourceTree = "<group>"; }; DED7D7310A524295003AD0FB /* Diagnostic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Diagnostic.h; sourceTree = "<group>"; }; DED7D7320A524295003AD0FB /* DiagnosticKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = DiagnosticKinds.def; sourceTree = "<group>"; }; DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = "<group>"; }; @@ -313,6 +319,8 @@ DE5932CD0AD60FF400BC794C /* clang.cpp */, DE5932CE0AD60FF400BC794C /* clang.h */, DED627020AE0C51D001E80A4 /* Targets.cpp */, + DED67AEF0B6DB92F00AAD4A3 /* PPCBuiltins.def */, + DED67AED0B6DB92A00AAD4A3 /* X86Builtins.def */, DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */, DE5932D00AD60FF400BC794C /* PrintPreprocessedOutput.cpp */, ); diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 9eefcdac403..4d089839524 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_ASTCONTEXT_H #define LLVM_CLANG_AST_ASTCONTEXT_H +#include "clang/AST/Builtins.h" #include "clang/AST/Type.h" #include <vector> @@ -33,6 +34,7 @@ class ASTContext { public: Preprocessor &PP; TargetInfo &Target; + Builtin::Context BuiltinInfo; // Builtin Types. TypeRef VoidTy; diff --git a/clang/include/clang/AST/Builtins.h b/clang/include/clang/AST/Builtins.h index b07e4aed0be..6049b3d2114 100644 --- a/clang/include/clang/AST/Builtins.h +++ b/clang/include/clang/AST/Builtins.h @@ -15,6 +15,8 @@ #ifndef LLVM_CLANG_AST_BUILTINS_H #define LLVM_CLANG_AST_BUILTINS_H +#include <cstring> + namespace llvm { namespace clang { class TargetInfo; @@ -27,24 +29,44 @@ enum ID { NotBuiltin = 0, // This is not a builtin function. #define BUILTIN(ID, TYPE, ATTRS) BI##ID, #include "clang/AST/Builtins.def" - FirstTargetSpecificBuiltin + FirstTSBuiltin }; struct Info { const char *Name, *Type, *Attributes; + + bool operator==(const Info &RHS) const { + return !strcmp(Name, RHS.Name) && + !strcmp(Type, RHS.Type) && + !strcmp(Attributes, RHS.Attributes); + } + bool operator!=(const Info &RHS) const { return !(*this == RHS); } }; -/// Builtin::GetName - Return the identifier name for the specified builtin, -/// e.g. "__builtin_abs". -const char *GetName(ID id); - -/// InitializeBuiltins - Mark the identifiers for all the builtins with their -/// appropriate builtin ID # and mark any non-portable builtin identifiers as -/// such. -void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target); - -/// GetBuiltinType - Return the type for the specified builtin. -TypeRef GetBuiltinType(ID id, ASTContext &Context); +/// Builtin::Context - This holds information about target-independent and +/// target-specific builtins, allowing easy queries by clients. +class Context { + const Info *TSRecords; + unsigned NumTSRecords; +public: + Context() : TSRecords(0), NumTSRecords(0) {} + + /// InitializeBuiltins - Mark the identifiers for all the builtins with their + /// appropriate builtin ID # and mark any non-portable builtin identifiers as + /// such. + void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target); + + /// Builtin::GetName - Return the identifier name for the specified builtin, + /// e.g. "__builtin_abs". + const char *GetName(unsigned ID) const { + return GetRecord(ID).Name; + } + + /// GetBuiltinType - Return the type for the specified builtin. + TypeRef GetBuiltinType(unsigned ID, ASTContext &Context) const; +private: + const Info &GetRecord(unsigned ID) const; +}; } } // end namespace clang diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 9fdfe587c2e..2a04981003d 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -23,6 +23,7 @@ namespace clang { class TargetInfoImpl; class Diagnostic; +namespace Builtin { struct Info; } /// TargetInfo - This class exposes information about the current target set. /// A target set consists of a primary target and zero or more secondary targets @@ -101,6 +102,12 @@ public: if (!WCharWidth) ComputeWCharWidth(Loc); return WCharWidth; } + + /// getTargetBuiltins - Return information about target-specific builtins for + /// the current primary target, and info about which builtins are non-portable + /// across the current set of primary and secondary targets. + void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords, + std::vector<const char *> &NonPortableBuiltins) const; private: void ComputeWCharWidth(SourceLocation Loc); @@ -129,6 +136,13 @@ public: /// unsigned getWCharWidth() const { return WCharWidth; } + /// getTargetBuiltins - Return information about target-specific builtins for + /// the target. + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + Records = 0; + NumRecords = 0; + } private: virtual void ANCHOR(); // out-of-line virtual method for class. }; |

