//===--- 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/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
using namespace clang;

static const Builtin::Info BuiltinInfo[] = {
  { "not a builtin function", 0, 0, 0, ALL_LANGUAGES },
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) { #ID, TYPE, ATTRS, HEADER,\
                                                            BUILTIN_LANG },
#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() {
  // Get the target specific builtins from the target.
  TSRecords = 0;
  NumTSRecords = 0;
}

void Builtin::Context::InitializeTarget(const TargetInfo &Target) {
  assert(NumTSRecords == 0 && "Already initialized target?");
  Target.getTargetBuiltins(TSRecords, NumTSRecords);  
}

bool Builtin::Context::BuiltinIsSupported(const Builtin::Info &BuiltinInfo,
                                          const LangOptions &LangOpts) {
  bool BuiltinsUnsupported = LangOpts.NoBuiltin &&
                             strchr(BuiltinInfo.Attributes, 'f');
  bool MathBuiltinsUnsupported =
    LangOpts.NoMathBuiltin && BuiltinInfo.HeaderName &&      
    llvm::StringRef(BuiltinInfo.HeaderName).equals("math.h");
  bool GnuModeUnsupported = !LangOpts.GNUMode &&
                            (BuiltinInfo.builtin_lang & GNU_LANG);
  bool ObjCUnsupported = !LangOpts.ObjC1 &&
                         BuiltinInfo.builtin_lang == OBJC_LANG;
  return !BuiltinsUnsupported && !MathBuiltinsUnsupported &&
         !GnuModeUnsupported && !ObjCUnsupported;
}

/// 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 LangOptions& LangOpts) {
  // Step #1: mark all target-independent builtins with their ID's.
  for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
    if (BuiltinIsSupported(BuiltinInfo[i], LangOpts)) {
      Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
    }

  // Step #2: Register target-specific builtins.
  for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
    if (!LangOpts.NoBuiltin || !strchr(TSRecords[i].Attributes, 'f'))
      Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
}

void
Builtin::Context::GetBuiltinNames(SmallVectorImpl<const char *> &Names) {
  // Final all target-independent names
  for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
    if (!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 (!strchr(TSRecords[i].Attributes, 'f'))
      Names.push_back(TSRecords[i].Name);
}

void Builtin::Context::ForgetBuiltin(unsigned ID, IdentifierTable &Table) {
  Table.get(GetRecord(ID).Name).setBuiltinID(0);
}

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;
}

// FIXME: Refactor with isPrintfLike.
bool
Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
                              bool &HasVAListArg) {
  const char *Scanf = strpbrk(GetRecord(ID).Attributes, "sS");
  if (!Scanf)
    return false;

  HasVAListArg = (*Scanf == 'S');

  ++Scanf;
  assert(*Scanf == ':' && "s or S specifier must have be followed by a ':'");
  ++Scanf;

  assert(strchr(Scanf, ':') && "printf specifier must end with a ':'");
  FormatIdx = strtol(Scanf, 0, 10);
  return true;
}

