//===--- 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/Basic/Builtins.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, 0, false }, #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false }, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false }, #include "clang/Basic/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]; } Builtin::Context::Context(const TargetInfo &Target) { // Get the target specific builtins from the target. TSRecords = 0; NumTSRecords = 0; Target.getTargetBuiltins(TSRecords, NumTSRecords); } /// 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, bool NoBuiltins) { // Step #1: mark all target-independent builtins with their ID's. for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i) if (!BuiltinInfo[i].Suppressed && (!NoBuiltins || !strchr(BuiltinInfo[i].Attributes, 'f'))) Table.get(BuiltinInfo[i].Name).setBuiltinID(i); // Step #2: Register target-specific builtins. for (unsigned i = 0, e = NumTSRecords; i != e; ++i) if (!TSRecords[i].Suppressed && (!NoBuiltins || (TSRecords[i].Attributes && !strchr(TSRecords[i].Attributes, 'f')))) Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin); } void Builtin::Context::GetBuiltinNames(llvm::SmallVectorImpl &Names, bool NoBuiltins) { // Final all target-independent names for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i) if (!BuiltinInfo[i].Suppressed && (!NoBuiltins || !strchr(BuiltinInfo[i].Attributes, 'f'))) Names.push_back(BuiltinInfo[i].Name); // Find target-specific names. for (unsigned i = 0, e = NumTSRecords; i != e; ++i) if (!TSRecords[i].Suppressed && (!NoBuiltins || (TSRecords[i].Attributes && !strchr(TSRecords[i].Attributes, 'f')))) Names.push_back(TSRecords[i].Name); } bool Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg) { const char *Printf = strpbrk(GetRecord(ID).Attributes, "pP"); if (!Printf) return false; HasVAListArg = (*Printf == 'P'); ++Printf; assert(*Printf == ':' && "p or P specifier must have be followed by a ':'"); ++Printf; assert(strchr(Printf, ':') && "printf specifier must end with a ':'"); FormatIdx = strtol(Printf, 0, 10); return true; }