//===-- ClangOpenCLBuiltinEmitter.cpp - Generate OpenCL Builtin handling --===//
//
//                     The LLVM Compiler Infrastructure
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// These backends consume the definitions of OpenCL builtin functions in
// clang/lib/Sema/OpenCLBuiltins.td and produce builtin handling code for
// inclusion in SemaLookup.cpp, or a test file that calls all declared builtins.
//
//===----------------------------------------------------------------------===//

#include "TableGenBackends.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"

using namespace llvm;

namespace {

// A list of signatures that are shared by one or more builtin functions.
struct BuiltinTableEntries {
  SmallVector<StringRef, 4> Names;
  std::vector<std::pair<const Record *, unsigned>> Signatures;
};

// This tablegen backend emits code for checking whether a function is an
// OpenCL builtin function. If so, all overloads of this function are
// added to the LookupResult. The generated include file is used by
// SemaLookup.cpp
//
// For a successful lookup of e.g. the "cos" builtin, isOpenCLBuiltin("cos")
// returns a pair <Index, Len>.
// BuiltinTable[Index] to BuiltinTable[Index + Len] contains the pairs
// <SigIndex, SigLen> of the overloads of "cos".
// SignatureTable[SigIndex] to SignatureTable[SigIndex + SigLen] contains
// one of the signatures of "cos". The SignatureTable entry can be
// referenced by other functions, e.g. "sin", to exploit the fact that
// many OpenCL builtins share the same signature.
//
// The file generated by this TableGen emitter contains the following:
//
//  * Structs and enums to represent types and function signatures.
//
//  * const char *FunctionExtensionTable[]
//    List of space-separated OpenCL extensions.  A builtin references an
//    entry in this table when the builtin requires a particular (set of)
//    extension(s) to be enabled.
//
//  * OpenCLTypeStruct TypeTable[]
//    Type information for return types and arguments.
//
//  * unsigned SignatureTable[]
//    A list of types representing function signatures.  Each entry is an index
//    into the above TypeTable.  Multiple entries following each other form a
//    signature, where the first entry is the return type and subsequent
//    entries are the argument types.
//
//  * OpenCLBuiltinStruct BuiltinTable[]
//    Each entry represents one overload of an OpenCL builtin function and
//    consists of an index into the SignatureTable and the number of arguments.
//
//  * std::pair<unsigned, unsigned> isOpenCLBuiltin(llvm::StringRef Name)
//    Find out whether a string matches an existing OpenCL builtin function
//    name and return an index into BuiltinTable and the number of overloads.
//
//  * void OCL2Qual(Sema&, OpenCLTypeStruct, std::vector<QualType>&)
//    Convert an OpenCLTypeStruct type to a list of QualType instances.
//    One OpenCLTypeStruct can represent multiple types, primarily when using
//    GenTypes.
//
class BuiltinNameEmitter {
public:
  BuiltinNameEmitter(const RecordKeeper &Records, raw_ostream &OS)
      : Records(Records), OS(OS) {}

  // Entrypoint to generate the functions and structures for checking
  // whether a function is an OpenCL builtin function.
  void Emit();

private:
  // A list of indices into the builtin function table.
  using BuiltinIndexListTy = SmallVector<unsigned, 11>;

  // Contains OpenCL builtin functions and related information, stored as
  // Record instances. They are coming from the associated TableGen file.
  const RecordKeeper &Records;

  // The output file.
  raw_ostream &OS;

  // Helper function for BuiltinNameEmitter::EmitDeclarations.  Generate enum
  // definitions in the Output string parameter, and save their Record instances
  // in the List parameter.
  // \param Types (in) List containing the Types to extract.
  // \param TypesSeen (inout) List containing the Types already extracted.
  // \param Output (out) String containing the enums to emit in the output file.
  // \param List (out) List containing the extracted Types, except the Types in
  //        TypesSeen.
  void ExtractEnumTypes(ArrayRef<const Record *> Types, StringSet<> &TypesSeen,
                        std::string &Output, std::vector<const Record *> &List);

  // Emit the enum or struct used in the generated file.
  // Populate the TypeList at the same time.
  void EmitDeclarations();

  // Parse the Records generated by TableGen to populate the SignaturesList,
  // FctOverloadMap and TypeMap.
  void GetOverloads();

  // Compare two lists of signatures and check that e.g. the OpenCL version,
  // function attributes, and extension are equal for each signature.
  // \param Candidate (in) Entry in the SignatureListMap to check.
  // \param SignatureList (in) List of signatures of the considered function.
  // \returns true if the two lists of signatures are identical.
  bool CanReuseSignature(
      BuiltinIndexListTy *Candidate,
      std::vector<std::pair<const Record *, unsigned>> &SignatureList);

  // Group functions with the same list of signatures by populating the
  // SignatureListMap.
  // Some builtin functions have the same list of signatures, for example the
  // "sin" and "cos" functions. To save space in the BuiltinTable, the
  // "isOpenCLBuiltin" function will have the same output for these two
  // function names.
  void GroupBySignature();

  // Emit the FunctionExtensionTable that lists all function extensions.
  void EmitExtensionTable();

  // Emit the TypeTable containing all types used by OpenCL builtins.
  void EmitTypeTable();

  // Emit the SignatureTable. This table contains all the possible signatures.
  // A signature is stored as a list of indexes of the TypeTable.
  // The first index references the return type (mandatory), and the followings
  // reference its arguments.
  // E.g.:
  // 15, 2, 15 can represent a function with the signature:
  // int func(float, int)
  // The "int" type being at the index 15 in the TypeTable.
  void EmitSignatureTable();

  // Emit the BuiltinTable table. This table contains all the overloads of
  // each function, and is a struct OpenCLBuiltinDecl.
  // E.g.:
  // // 891 convert_float2_rtn
  //   { 58, 2, 3, 100, 0 },
  // This means that the signature of this convert_float2_rtn overload has
  // 1 argument (+1 for the return type), stored at index 58 in
  // the SignatureTable.  This prototype requires extension "3" in the
  // FunctionExtensionTable.  The last two values represent the minimum (1.0)
  // and maximum (0, meaning no max version) OpenCL version in which this
  // overload is supported.
  void EmitBuiltinTable();

  // Emit a StringMatcher function to check whether a function name is an
  // OpenCL builtin function name.
  void EmitStringMatcher();

  // Emit a function returning the clang QualType instance associated with
  // the TableGen Record Type.
  void EmitQualTypeFinder();

  // Contains a list of the available signatures, without the name of the
  // function. Each pair consists of a signature and a cumulative index.
  // E.g.:  <<float, float>, 0>,
  //        <<float, int, int, 2>>,
  //        <<float>, 5>,
  //        ...
  //        <<double, double>, 35>.
  std::vector<std::pair<std::vector<const Record *>, unsigned>> SignaturesList;

  // Map the name of a builtin function to its prototypes (instances of the
  // TableGen "Builtin" class).
  // Each prototype is registered as a pair of:
  //   <pointer to the "Builtin" instance,
  //    cumulative index of the associated signature in the SignaturesList>
  // E.g.:  The function cos: (float cos(float), double cos(double), ...)
  //        <"cos", <<ptrToPrototype0, 5>,
  //                 <ptrToPrototype1, 35>,
  //                 <ptrToPrototype2, 79>>
  // ptrToPrototype1 has the following signature: <double, double>
  MapVector<StringRef, std::vector<std::pair<const Record *, unsigned>>>
      FctOverloadMap;

  // Contains the map of OpenCL types to their index in the TypeTable.
  MapVector<const Record *, unsigned> TypeMap;

  // List of OpenCL function extensions mapping extension strings to
  // an index into the FunctionExtensionTable.
  StringMap<unsigned> FunctionExtensionIndex;

  // List of OpenCL type names in the same order as in enum OpenCLTypeID.
  // This list does not contain generic types.
  std::vector<const Record *> TypeList;

  // Same as TypeList, but for generic types only.
  std::vector<const Record *> GenTypeList;

  // Map an ordered vector of signatures to their original Record instances,
  // and to a list of function names that share these signatures.
  //
  // For example, suppose the "cos" and "sin" functions have only three
  // signatures, and these signatures are at index Ix in the SignatureTable:
  //          cos         |         sin         |  Signature    | Index
  //  float   cos(float)  | float   sin(float)  |  Signature1   | I1
  //  double  cos(double) | double  sin(double) |  Signature2   | I2
  //  half    cos(half)   | half    sin(half)   |  Signature3   | I3
  //
  // Then we will create a mapping of the vector of signatures:
  // SignatureListMap[<I1, I2, I3>] = <
  //                  <"cos", "sin">,
  //                  <Signature1, Signature2, Signature3>>
  // The function "tan", having the same signatures, would be mapped to the
  // same entry (<I1, I2, I3>).
  MapVector<BuiltinIndexListTy *, BuiltinTableEntries> SignatureListMap;
};

/// Base class for emitting a file (e.g. header or test) from OpenCLBuiltins.td
class OpenCLBuiltinFileEmitterBase {
public:
  OpenCLBuiltinFileEmitterBase(const RecordKeeper &Records, raw_ostream &OS)
      : Records(Records), OS(OS) {}
  virtual ~OpenCLBuiltinFileEmitterBase() = default;

  // Entrypoint to generate the functions for testing all OpenCL builtin
  // functions.
  virtual void emit() = 0;

protected:
  struct TypeFlags {
    TypeFlags() : IsConst(false), IsVolatile(false), IsPointer(false) {}
    bool IsConst : 1;
    bool IsVolatile : 1;
    bool IsPointer : 1;
    StringRef AddrSpace;
  };

  // Return a string representation of the given type, such that it can be
  // used as a type in OpenCL C code.
  std::string getTypeString(const Record *Type, TypeFlags Flags,
                            int VectorSize) const;

  // Return the type(s) and vector size(s) for the given type.  For
  // non-GenericTypes, the resulting vectors will contain 1 element.  For
  // GenericTypes, the resulting vectors typically contain multiple elements.
  void getTypeLists(const Record *Type, TypeFlags &Flags,
                    std::vector<const Record *> &TypeList,
                    std::vector<int64_t> &VectorList) const;

  // Expand the TableGen Records representing a builtin function signature into
  // one or more function signatures.  Return them as a vector of a vector of
  // strings, with each string containing an OpenCL C type and optional
  // qualifiers.
  //
  // The Records may contain GenericTypes, which expand into multiple
  // signatures.  Repeated occurrences of GenericType in a signature expand to
  // the same types.  For example [char, FGenType, FGenType] expands to:
  //   [char, float, float]
  //   [char, float2, float2]
  //   [char, float3, float3]
  //   ...
  void
  expandTypesInSignature(ArrayRef<const Record *> Signature,
                         SmallVectorImpl<SmallVector<std::string, 2>> &Types);

  // Emit extension enabling pragmas.
  void emitExtensionSetup();

  // Emit an #if guard for a Builtin's extension.  Return the corresponding
  // closing #endif, or an empty string if no extension #if guard was emitted.
  std::string emitExtensionGuard(const Record *Builtin);

  // Emit an #if guard for a Builtin's language version.  Return the
  // corresponding closing #endif, or an empty string if no version #if guard
  // was emitted.
  std::string emitVersionGuard(const Record *Builtin);

  // Emit an #if guard for all type extensions required for the given type
  // strings.  Return the corresponding closing #endif, or an empty string
  // if no extension #if guard was emitted.
  StringRef
  emitTypeExtensionGuards(const SmallVectorImpl<std::string> &Signature);

  // Map type strings to type extensions (e.g. "half2" -> "cl_khr_fp16").
  StringMap<StringRef> TypeExtMap;

  // Contains OpenCL builtin functions and related information, stored as
  // Record instances. They are coming from the associated TableGen file.
  const RecordKeeper &Records;

  // The output file.
  raw_ostream &OS;
};

// OpenCL builtin test generator.  This class processes the same TableGen input
// as BuiltinNameEmitter, but generates a .cl file that contains a call to each
// builtin function described in the .td input.
class OpenCLBuiltinTestEmitter : public OpenCLBuiltinFileEmitterBase {
public:
  OpenCLBuiltinTestEmitter(const RecordKeeper &Records, raw_ostream &OS)
      : OpenCLBuiltinFileEmitterBase(Records, OS) {}

  // Entrypoint to generate the functions for testing all OpenCL builtin
  // functions.
  void emit() override;
};

// OpenCL builtin header generator.  This class processes the same TableGen
// input as BuiltinNameEmitter, but generates a .h file that contains a
// prototype for each builtin function described in the .td input.
class OpenCLBuiltinHeaderEmitter : public OpenCLBuiltinFileEmitterBase {
public:
  OpenCLBuiltinHeaderEmitter(const RecordKeeper &Records, raw_ostream &OS)
      : OpenCLBuiltinFileEmitterBase(Records, OS) {}

  // Entrypoint to generate the header.
  void emit() override;
};

} // namespace

void BuiltinNameEmitter::Emit() {
  emitSourceFileHeader("OpenCL Builtin handling", OS, Records);

  OS << "#include \"llvm/ADT/StringRef.h\"\n";
  OS << "using namespace clang;\n\n";

  // Emit enums and structs.
  EmitDeclarations();

  // Parse the Records to populate the internal lists.
  GetOverloads();
  GroupBySignature();

  // Emit tables.
  EmitExtensionTable();
  EmitTypeTable();
  EmitSignatureTable();
  EmitBuiltinTable();

  // Emit functions.
  EmitStringMatcher();
  EmitQualTypeFinder();
}

void BuiltinNameEmitter::ExtractEnumTypes(ArrayRef<const Record *> Types,
                                          StringSet<> &TypesSeen,
                                          std::string &Output,
                                          std::vector<const Record *> &List) {
  raw_string_ostream SS(Output);

  for (const auto *T : Types) {
    if (!TypesSeen.contains(T->getValueAsString("Name"))) {
      SS << "  OCLT_" + T->getValueAsString("Name") << ",\n";
      // Save the type names in the same order as their enum value. Note that
      // the Record can be a VectorType or something else, only the name is
      // important.
      List.push_back(T);
      TypesSeen.insert(T->getValueAsString("Name"));
    }
  }
}

void BuiltinNameEmitter::EmitDeclarations() {
  // Enum of scalar type names (float, int, ...) and generic type sets.
  OS << "enum OpenCLTypeID {\n";

  StringSet<> TypesSeen;
  std::string GenTypeEnums;
  std::string TypeEnums;

  // Extract generic types and non-generic types separately, to keep
  // gentypes at the end of the enum which simplifies the special handling
  // for gentypes in SemaLookup.
  ArrayRef<const Record *> GenTypes =
      Records.getAllDerivedDefinitions("GenericType");
  ExtractEnumTypes(GenTypes, TypesSeen, GenTypeEnums, GenTypeList);

  ArrayRef<const Record *> Types = Records.getAllDerivedDefinitions("Type");
  ExtractEnumTypes(Types, TypesSeen, TypeEnums, TypeList);

  OS << TypeEnums;
  OS << GenTypeEnums;
  OS << "};\n";

  // Structure definitions.
  OS << R"(
// Image access qualifier.
enum OpenCLAccessQual : unsigned char {
  OCLAQ_None,
  OCLAQ_ReadOnly,
  OCLAQ_WriteOnly,
  OCLAQ_ReadWrite
};

// Represents a return type or argument type.
struct OpenCLTypeStruct {
  // A type (e.g. float, int, ...).
  const OpenCLTypeID ID;
  // Vector size (if applicable; 0 for scalars and generic types).
  const unsigned VectorWidth;
  // 0 if the type is not a pointer.
  const bool IsPointer : 1;
  // 0 if the type is not const.
  const bool IsConst : 1;
  // 0 if the type is not volatile.
  const bool IsVolatile : 1;
  // Access qualifier.
  const OpenCLAccessQual AccessQualifier;
  // Address space of the pointer (if applicable).
  const LangAS AS;
};

// One overload of an OpenCL builtin function.
struct OpenCLBuiltinStruct {
  // Index of the signature in the OpenCLTypeStruct table.
  const unsigned SigTableIndex;
  // Entries between index SigTableIndex and (SigTableIndex + NumTypes - 1) in
  // the SignatureTable represent the complete signature.  The first type at
  // index SigTableIndex is the return type.
  const unsigned NumTypes;
  // Function attribute __attribute__((pure))
  const bool IsPure : 1;
  // Function attribute __attribute__((const))
  const bool IsConst : 1;
  // Function attribute __attribute__((convergent))
  const bool IsConv : 1;
  // OpenCL extension(s) required for this overload.
  const unsigned short Extension;
  // OpenCL versions in which this overload is available.
  const unsigned short Versions;
};

)";
}

// Verify that the combination of GenTypes in a signature is supported.
// To simplify the logic for creating overloads in SemaLookup, only allow
// a signature to contain different GenTypes if these GenTypes represent
// the same number of actual scalar or vector types.
//
// Exit with a fatal error if an unsupported construct is encountered.
static void VerifySignature(ArrayRef<const Record *> Signature,
                            const Record *BuiltinRec) {
  unsigned GenTypeVecSizes = 1;
  unsigned GenTypeTypes = 1;

  for (const auto *T : Signature) {
    // Check all GenericType arguments in this signature.
    if (T->isSubClassOf("GenericType")) {
      // Check number of vector sizes.
      unsigned NVecSizes =
          T->getValueAsDef("VectorList")->getValueAsListOfInts("List").size();
      if (NVecSizes != GenTypeVecSizes && NVecSizes != 1) {
        if (GenTypeVecSizes > 1) {
          // We already saw a gentype with a different number of vector sizes.
          PrintFatalError(BuiltinRec->getLoc(),
              "number of vector sizes should be equal or 1 for all gentypes "
              "in a declaration");
        }
        GenTypeVecSizes = NVecSizes;
      }

      // Check number of data types.
      unsigned NTypes =
          T->getValueAsDef("TypeList")->getValueAsListOfDefs("List").size();
      if (NTypes != GenTypeTypes && NTypes != 1) {
        if (GenTypeTypes > 1) {
          // We already saw a gentype with a different number of types.
          PrintFatalError(BuiltinRec->getLoc(),
              "number of types should be equal or 1 for all gentypes "
              "in a declaration");
        }
        GenTypeTypes = NTypes;
      }
    }
  }
}

void BuiltinNameEmitter::GetOverloads() {
  // Populate the TypeMap.
  ArrayRef<const Record *> Types = Records.getAllDerivedDefinitions("Type");
  unsigned I = 0;
  for (const auto &T : Types) {
    TypeMap.insert(std::make_pair(T, I++));
  }

  // Populate the SignaturesList and the FctOverloadMap.
  unsigned CumulativeSignIndex = 0;
  ArrayRef<const Record *> Builtins =
      Records.getAllDerivedDefinitions("Builtin");
  for (const auto *B : Builtins) {
    StringRef BName = B->getValueAsString("Name");
    FctOverloadMap.try_emplace(BName);

    auto Signature = B->getValueAsListOfDefs("Signature");
    // Reuse signatures to avoid unnecessary duplicates.
    auto it =
        find_if(SignaturesList,
                [&](const std::pair<std::vector<const Record *>, unsigned> &a) {
                  return a.first == Signature;
                });
    unsigned SignIndex;
    if (it == SignaturesList.end()) {
      VerifySignature(Signature, B);
      SignaturesList.push_back(std::make_pair(Signature, CumulativeSignIndex));
      SignIndex = CumulativeSignIndex;
      CumulativeSignIndex += Signature.size();
    } else {
      SignIndex = it->second;
    }
    FctOverloadMap[BName].push_back(std::make_pair(B, SignIndex));
  }
}

void BuiltinNameEmitter::EmitExtensionTable() {
  OS << "static const char *FunctionExtensionTable[] = {\n";
  unsigned Index = 0;
  ArrayRef<const Record *> FuncExtensions =
      Records.getAllDerivedDefinitions("FunctionExtension");

  for (const auto &FE : FuncExtensions) {
    // Emit OpenCL extension table entry.
    OS << "  // " << Index << ": " << FE->getName() << "\n"
       << "  \"" << FE->getValueAsString("ExtName") << "\",\n";

    // Record index of this extension.
    FunctionExtensionIndex[FE->getName()] = Index++;
  }
  OS << "};\n\n";
}

void BuiltinNameEmitter::EmitTypeTable() {
  OS << "static const OpenCLTypeStruct TypeTable[] = {\n";
  for (const auto &T : TypeMap) {
    const char *AccessQual =
        StringSwitch<const char *>(T.first->getValueAsString("AccessQualifier"))
            .Case("RO", "OCLAQ_ReadOnly")
            .Case("WO", "OCLAQ_WriteOnly")
            .Case("RW", "OCLAQ_ReadWrite")
            .Default("OCLAQ_None");

    OS << "  // " << T.second << "\n"
       << "  {OCLT_" << T.first->getValueAsString("Name") << ", "
       << T.first->getValueAsInt("VecWidth") << ", "
       << T.first->getValueAsBit("IsPointer") << ", "
       << T.first->getValueAsBit("IsConst") << ", "
       << T.first->getValueAsBit("IsVolatile") << ", "
       << AccessQual << ", "
       << T.first->getValueAsString("AddrSpace") << "},\n";
  }
  OS << "};\n\n";
}

void BuiltinNameEmitter::EmitSignatureTable() {
  // Store a type (e.g. int, float, int2, ...). The type is stored as an index
  // of a struct OpenCLType table. Multiple entries following each other form a
  // signature.
  OS << "static const unsigned short SignatureTable[] = {\n";
  for (const auto &P : SignaturesList) {
    OS << "  // " << P.second << "\n  ";
    for (const Record *R : P.first) {
      unsigned Entry = TypeMap.find(R)->second;
      if (Entry > USHRT_MAX) {
        // Report an error when seeing an entry that is too large for the
        // current index type (unsigned short).  When hitting this, the type
        // of SignatureTable will need to be changed.
        PrintFatalError("Entry in SignatureTable exceeds limit.");
      }
      OS << Entry << ", ";
    }
    OS << "\n";
  }
  OS << "};\n\n";
}

// Encode a range MinVersion..MaxVersion into a single bit mask that can be
// checked against LangOpts using isOpenCLVersionContainedInMask().
// This must be kept in sync with OpenCLVersionID in OpenCLOptions.h.
// (Including OpenCLOptions.h here would be a layering violation.)
static unsigned short EncodeVersions(unsigned int MinVersion,
                                     unsigned int MaxVersion) {
  unsigned short Encoded = 0;

  // A maximum version of 0 means available in all later versions.
  if (MaxVersion == 0) {
    MaxVersion = UINT_MAX;
  }

  unsigned VersionIDs[] = {100, 110, 120, 200, 300};
  for (unsigned I = 0; I < std::size(VersionIDs); I++) {
    if (VersionIDs[I] >= MinVersion && VersionIDs[I] < MaxVersion) {
      Encoded |= 1 << I;
    }
  }

  return Encoded;
}

void BuiltinNameEmitter::EmitBuiltinTable() {
  unsigned Index = 0;

  OS << "static const OpenCLBuiltinStruct BuiltinTable[] = {\n";
  for (const auto &SLM : SignatureListMap) {

    OS << "  // " << (Index + 1) << ": ";
    for (const auto &Name : SLM.second.Names) {
      OS << Name << ", ";
    }
    OS << "\n";

    for (const auto &Overload : SLM.second.Signatures) {
      StringRef ExtName = Overload.first->getValueAsDef("Extension")->getName();
      unsigned int MinVersion =
          Overload.first->getValueAsDef("MinVersion")->getValueAsInt("ID");
      unsigned int MaxVersion =
          Overload.first->getValueAsDef("MaxVersion")->getValueAsInt("ID");

      OS << "  { " << Overload.second << ", "
         << Overload.first->getValueAsListOfDefs("Signature").size() << ", "
         << (Overload.first->getValueAsBit("IsPure")) << ", "
         << (Overload.first->getValueAsBit("IsConst")) << ", "
         << (Overload.first->getValueAsBit("IsConv")) << ", "
         << FunctionExtensionIndex[ExtName] << ", "
         << EncodeVersions(MinVersion, MaxVersion) << " },\n";
      Index++;
    }
  }
  OS << "};\n\n";
}

bool BuiltinNameEmitter::CanReuseSignature(
    BuiltinIndexListTy *Candidate,
    std::vector<std::pair<const Record *, unsigned>> &SignatureList) {
  assert(Candidate->size() == SignatureList.size() &&
         "signature lists should have the same size");

  auto &CandidateSigs =
      SignatureListMap.find(Candidate)->second.Signatures;
  for (unsigned Index = 0; Index < Candidate->size(); Index++) {
    const Record *Rec = SignatureList[Index].first;
    const Record *Rec2 = CandidateSigs[Index].first;
    if (Rec->getValueAsBit("IsPure") == Rec2->getValueAsBit("IsPure") &&
        Rec->getValueAsBit("IsConst") == Rec2->getValueAsBit("IsConst") &&
        Rec->getValueAsBit("IsConv") == Rec2->getValueAsBit("IsConv") &&
        Rec->getValueAsDef("MinVersion")->getValueAsInt("ID") ==
            Rec2->getValueAsDef("MinVersion")->getValueAsInt("ID") &&
        Rec->getValueAsDef("MaxVersion")->getValueAsInt("ID") ==
            Rec2->getValueAsDef("MaxVersion")->getValueAsInt("ID") &&
        Rec->getValueAsDef("Extension")->getName() ==
            Rec2->getValueAsDef("Extension")->getName()) {
      return true;
    }
  }
  return false;
}

void BuiltinNameEmitter::GroupBySignature() {
  // List of signatures known to be emitted.
  std::vector<BuiltinIndexListTy *> KnownSignatures;

  for (auto &Fct : FctOverloadMap) {
    bool FoundReusableSig = false;

    // Gather all signatures for the current function.
    auto *CurSignatureList = new BuiltinIndexListTy();
    for (const auto &Signature : Fct.second) {
      CurSignatureList->push_back(Signature.second);
    }
    // Sort the list to facilitate future comparisons.
    sort(*CurSignatureList);

    // Check if we have already seen another function with the same list of
    // signatures.  If so, just add the name of the function.
    for (auto *Candidate : KnownSignatures) {
      if (Candidate->size() == CurSignatureList->size() &&
          *Candidate == *CurSignatureList) {
        if (CanReuseSignature(Candidate, Fct.second)) {
          SignatureListMap.find(Candidate)->second.Names.push_back(Fct.first);
          FoundReusableSig = true;
        }
      }
    }

    if (FoundReusableSig) {
      delete CurSignatureList;
    } else {
      // Add a new entry.
      SignatureListMap[CurSignatureList] = {
          SmallVector<StringRef, 4>(1, Fct.first), Fct.second};
      KnownSignatures.push_back(CurSignatureList);
    }
  }

  for (auto *I : KnownSignatures) {
    delete I;
  }
}

void BuiltinNameEmitter::EmitStringMatcher() {
  std::vector<StringMatcher::StringPair> ValidBuiltins;
  unsigned CumulativeIndex = 1;

  for (const auto &SLM : SignatureListMap) {
    const auto &Ovl = SLM.second.Signatures;

    // A single signature list may be used by different builtins.  Return the
    // same <index, length> pair for each of those builtins.
    for (const auto &FctName : SLM.second.Names) {
      std::string RetStmt;
      raw_string_ostream SS(RetStmt);
      SS << "return std::make_pair(" << CumulativeIndex << ", " << Ovl.size()
         << ");";
      ValidBuiltins.push_back(
          StringMatcher::StringPair(std::string(FctName), RetStmt));
    }
    CumulativeIndex += Ovl.size();
  }

  OS << R"(
// Find out whether a string matches an existing OpenCL builtin function name.
// Returns: A pair <0, 0> if no name matches.
//          A pair <Index, Len> indexing the BuiltinTable if the name is
//          matching an OpenCL builtin function.
static std::pair<unsigned, unsigned> isOpenCLBuiltin(llvm::StringRef Name) {

)";

  StringMatcher("Name", ValidBuiltins, OS).Emit(0, true);

  OS << "  return std::make_pair(0, 0);\n";
  OS << "} // isOpenCLBuiltin\n";
}

// Emit an if-statement with an isMacroDefined call for each extension in
// the space-separated list of extensions.
static void EmitMacroChecks(raw_ostream &OS, StringRef Extensions) {
  SmallVector<StringRef, 2> ExtVec;
  Extensions.split(ExtVec, " ");
  OS << "      if (";
  for (StringRef Ext : ExtVec) {
    if (Ext != ExtVec.front())
      OS << " && ";
    OS << "S.getPreprocessor().isMacroDefined(\"" << Ext << "\")";
  }
  OS << ") {\n  ";
}

void BuiltinNameEmitter::EmitQualTypeFinder() {
  OS << R"(

static QualType getOpenCLEnumType(Sema &S, llvm::StringRef Name);
static QualType getOpenCLTypedefType(Sema &S, llvm::StringRef Name);

// Convert an OpenCLTypeStruct type to a list of QualTypes.
// Generic types represent multiple types and vector sizes, thus a vector
// is returned. The conversion is done in two steps:
// Step 1: A switch statement fills a vector with scalar base types for the
//         Cartesian product of (vector sizes) x (types) for generic types,
//         or a single scalar type for non generic types.
// Step 2: Qualifiers and other type properties such as vector size are
//         applied.
static void OCL2Qual(Sema &S, const OpenCLTypeStruct &Ty,
                     llvm::SmallVectorImpl<QualType> &QT) {
  ASTContext &Context = S.Context;
  // Number of scalar types in the GenType.
  unsigned GenTypeNumTypes;
  // Pointer to the list of vector sizes for the GenType.
  llvm::ArrayRef<unsigned> GenVectorSizes;
)";

  // Generate list of vector sizes for each generic type.
  for (const auto *VectList : Records.getAllDerivedDefinitions("IntList")) {
    OS << "  constexpr unsigned List"
       << VectList->getValueAsString("Name") << "[] = {";
    for (const auto V : VectList->getValueAsListOfInts("List")) {
      OS << V << ", ";
    }
    OS << "};\n";
  }

  // Step 1.
  // Start of switch statement over all types.
  OS << "\n  switch (Ty.ID) {\n";

  // Switch cases for image types (Image2d, Image3d, ...)
  ArrayRef<const Record *> ImageTypes =
      Records.getAllDerivedDefinitions("ImageType");

  // Map an image type name to its 3 access-qualified types (RO, WO, RW).
  StringMap<SmallVector<const Record *, 3>> ImageTypesMap;
  for (auto *IT : ImageTypes)
    ImageTypesMap[IT->getValueAsString("Name")].push_back(IT);

  // Emit the cases for the image types.  For an image type name, there are 3
  // corresponding QualTypes ("RO", "WO", "RW").  The "AccessQualifier" field
  // tells which one is needed.  Emit a switch statement that puts the
  // corresponding QualType into "QT".
  for (const auto &ITE : ImageTypesMap) {
    OS << "    case OCLT_" << ITE.getKey() << ":\n"
       << "      switch (Ty.AccessQualifier) {\n"
       << "        case OCLAQ_None:\n"
       << "          llvm_unreachable(\"Image without access qualifier\");\n";
    for (const auto &Image : ITE.getValue()) {
      StringRef Exts =
          Image->getValueAsDef("Extension")->getValueAsString("ExtName");
      OS << StringSwitch<const char *>(
                Image->getValueAsString("AccessQualifier"))
                .Case("RO", "        case OCLAQ_ReadOnly:\n")
                .Case("WO", "        case OCLAQ_WriteOnly:\n")
                .Case("RW", "        case OCLAQ_ReadWrite:\n");
      if (!Exts.empty()) {
        OS << "    ";
        EmitMacroChecks(OS, Exts);
      }
      OS << "          QT.push_back("
         << Image->getValueAsDef("QTExpr")->getValueAsString("TypeExpr")
         << ");\n";
      if (!Exts.empty()) {
        OS << "          }\n";
      }
      OS << "          break;\n";
    }
    OS << "      }\n"
       << "      break;\n";
  }

  // Switch cases for generic types.
  for (const auto *GenType : Records.getAllDerivedDefinitions("GenericType")) {
    OS << "    case OCLT_" << GenType->getValueAsString("Name") << ": {\n";

    // Build the Cartesian product of (vector sizes) x (types).  Only insert
    // the plain scalar types for now; other type information such as vector
    // size and type qualifiers will be added after the switch statement.
    std::vector<const Record *> BaseTypes =
        GenType->getValueAsDef("TypeList")->getValueAsListOfDefs("List");

    // Collect all QualTypes for a single vector size into TypeList.
    OS << "      SmallVector<QualType, " << BaseTypes.size() << "> TypeList;\n";
    for (const auto *T : BaseTypes) {
      StringRef Exts =
          T->getValueAsDef("Extension")->getValueAsString("ExtName");
      if (!Exts.empty()) {
        EmitMacroChecks(OS, Exts);
      }
      OS << "      TypeList.push_back("
         << T->getValueAsDef("QTExpr")->getValueAsString("TypeExpr") << ");\n";
      if (!Exts.empty()) {
        OS << "      }\n";
      }
    }
    OS << "      GenTypeNumTypes = TypeList.size();\n";

    // Duplicate the TypeList for every vector size.
    std::vector<int64_t> VectorList =
        GenType->getValueAsDef("VectorList")->getValueAsListOfInts("List");
    OS << "      QT.reserve(" << VectorList.size() * BaseTypes.size() << ");\n"
       << "      for (unsigned I = 0; I < " << VectorList.size() << "; I++) {\n"
       << "        QT.append(TypeList);\n"
       << "      }\n";

    // GenVectorSizes is the list of vector sizes for this GenType.
    OS << "      GenVectorSizes = List"
       << GenType->getValueAsDef("VectorList")->getValueAsString("Name")
       << ";\n"
       << "      break;\n"
       << "    }\n";
  }

  // Switch cases for non generic, non image types (int, int4, float, ...).
  // Only insert the plain scalar type; vector information and type qualifiers
  // are added in step 2.
  ArrayRef<const Record *> Types = Records.getAllDerivedDefinitions("Type");
  StringSet<> TypesSeen;

  for (const auto *T : Types) {
    // Check this is not an image type
    if (ImageTypesMap.contains(T->getValueAsString("Name")))
      continue;
    // Check we have not seen this Type
    if (!TypesSeen.insert(T->getValueAsString("Name")).second)
      continue;

    // Check the Type does not have an "abstract" QualType
    auto QT = T->getValueAsDef("QTExpr");
    if (QT->getValueAsBit("IsAbstract") == 1)
      continue;
    // Emit the cases for non generic, non image types.
    OS << "    case OCLT_" << T->getValueAsString("Name") << ":\n";

    StringRef Exts = T->getValueAsDef("Extension")->getValueAsString("ExtName");
    // If this type depends on an extension, ensure the extension macros are
    // defined.
    if (!Exts.empty()) {
      EmitMacroChecks(OS, Exts);
    }
    OS << "      QT.push_back(" << QT->getValueAsString("TypeExpr") << ");\n";
    if (!Exts.empty()) {
      OS << "      }\n";
    }
    OS << "      break;\n";
  }

  // End of switch statement.
  OS << "  } // end of switch (Ty.ID)\n\n";

  // Step 2.
  // Add ExtVector types if this was a generic type, as the switch statement
  // above only populated the list with scalar types.  This completes the
  // construction of the Cartesian product of (vector sizes) x (types).
  OS << "  // Construct the different vector types for each generic type.\n";
  OS << "  if (Ty.ID >= " << TypeList.size() << ") {";
  OS << R"(
    for (unsigned I = 0; I < QT.size(); I++) {
      // For scalars, size is 1.
      if (GenVectorSizes[I / GenTypeNumTypes] != 1) {
        QT[I] = Context.getExtVectorType(QT[I],
                          GenVectorSizes[I / GenTypeNumTypes]);
      }
    }
  }
)";

  // Assign the right attributes to the types (e.g. vector size).
  OS << R"(
  // Set vector size for non-generic vector types.
  if (Ty.VectorWidth > 1) {
    for (unsigned Index = 0; Index < QT.size(); Index++) {
      QT[Index] = Context.getExtVectorType(QT[Index], Ty.VectorWidth);
    }
  }

  if (Ty.IsVolatile != 0) {
    for (unsigned Index = 0; Index < QT.size(); Index++) {
      QT[Index] = Context.getVolatileType(QT[Index]);
    }
  }

  if (Ty.IsConst != 0) {
    for (unsigned Index = 0; Index < QT.size(); Index++) {
      QT[Index] = Context.getConstType(QT[Index]);
    }
  }

  // Transform the type to a pointer as the last step, if necessary.
  // Builtin functions only have pointers on [const|volatile], no
  // [const|volatile] pointers, so this is ok to do it as a last step.
  if (Ty.IsPointer != 0) {
    for (unsigned Index = 0; Index < QT.size(); Index++) {
      QT[Index] = Context.getAddrSpaceQualType(QT[Index], Ty.AS);
      QT[Index] = Context.getPointerType(QT[Index]);
    }
  }
)";

  // End of the "OCL2Qual" function.
  OS << "\n} // OCL2Qual\n";
}

std::string OpenCLBuiltinFileEmitterBase::getTypeString(const Record *Type,
                                                        TypeFlags Flags,
                                                        int VectorSize) const {
  std::string S;
  if (Type->getValueAsBit("IsConst") || Flags.IsConst) {
    S += "const ";
  }
  if (Type->getValueAsBit("IsVolatile") || Flags.IsVolatile) {
    S += "volatile ";
  }

  auto PrintAddrSpace = [&S](StringRef AddrSpace) {
    S += StringSwitch<const char *>(AddrSpace)
             .Case("clang::LangAS::opencl_private", "__private")
             .Case("clang::LangAS::opencl_global", "__global")
             .Case("clang::LangAS::opencl_constant", "__constant")
             .Case("clang::LangAS::opencl_local", "__local")
             .Case("clang::LangAS::opencl_generic", "__generic")
             .Default("__private");
    S += " ";
  };
  if (Flags.IsPointer) {
    PrintAddrSpace(Flags.AddrSpace);
  } else if (Type->getValueAsBit("IsPointer")) {
    PrintAddrSpace(Type->getValueAsString("AddrSpace"));
  }

  StringRef Acc = Type->getValueAsString("AccessQualifier");
  if (Acc != "") {
    S += StringSwitch<const char *>(Acc)
             .Case("RO", "__read_only ")
             .Case("WO", "__write_only ")
             .Case("RW", "__read_write ");
  }

  S += Type->getValueAsString("Name").str();
  if (VectorSize > 1) {
    S += std::to_string(VectorSize);
  }

  if (Type->getValueAsBit("IsPointer") || Flags.IsPointer) {
    S += " *";
  }

  return S;
}

void OpenCLBuiltinFileEmitterBase::getTypeLists(
    const Record *Type, TypeFlags &Flags, std::vector<const Record *> &TypeList,
    std::vector<int64_t> &VectorList) const {
  bool isGenType = Type->isSubClassOf("GenericType");
  if (isGenType) {
    TypeList = Type->getValueAsDef("TypeList")->getValueAsListOfDefs("List");
    VectorList =
        Type->getValueAsDef("VectorList")->getValueAsListOfInts("List");
    return;
  }

  if (Type->isSubClassOf("PointerType") || Type->isSubClassOf("ConstType") ||
      Type->isSubClassOf("VolatileType")) {
    StringRef SubTypeName = Type->getValueAsString("Name");
    const Record *PossibleGenType = Records.getDef(SubTypeName);
    if (PossibleGenType && PossibleGenType->isSubClassOf("GenericType")) {
      // When PointerType, ConstType, or VolatileType is applied to a
      // GenericType, the flags need to be taken from the subtype, not from the
      // GenericType.
      Flags.IsPointer = Type->getValueAsBit("IsPointer");
      Flags.IsConst = Type->getValueAsBit("IsConst");
      Flags.IsVolatile = Type->getValueAsBit("IsVolatile");
      Flags.AddrSpace = Type->getValueAsString("AddrSpace");
      getTypeLists(PossibleGenType, Flags, TypeList, VectorList);
      return;
    }
  }

  // Not a GenericType, so just insert the single type.
  TypeList.push_back(Type);
  VectorList.push_back(Type->getValueAsInt("VecWidth"));
}

void OpenCLBuiltinFileEmitterBase::expandTypesInSignature(
    ArrayRef<const Record *> Signature,
    SmallVectorImpl<SmallVector<std::string, 2>> &Types) {
  // Find out if there are any GenTypes in this signature, and if so, calculate
  // into how many signatures they will expand.
  unsigned NumSignatures = 1;
  SmallVector<SmallVector<std::string, 4>, 4> ExpandedGenTypes;
  for (const auto &Arg : Signature) {
    SmallVector<std::string, 4> ExpandedArg;
    std::vector<const Record *> TypeList;
    std::vector<int64_t> VectorList;
    TypeFlags Flags;

    getTypeLists(Arg, Flags, TypeList, VectorList);

    // Insert the Cartesian product of the types and vector sizes.
    for (const auto &Vector : VectorList) {
      for (const auto &Type : TypeList) {
        std::string FullType = getTypeString(Type, Flags, Vector);
        ExpandedArg.push_back(FullType);

        // If the type requires an extension, add a TypeExtMap entry mapping
        // the full type name to the extension.
        StringRef Ext =
            Type->getValueAsDef("Extension")->getValueAsString("ExtName");
        if (!Ext.empty())
          TypeExtMap.try_emplace(FullType, Ext);
      }
    }
    NumSignatures = std::max<unsigned>(NumSignatures, ExpandedArg.size());
    ExpandedGenTypes.push_back(ExpandedArg);
  }

  // Now the total number of signatures is known.  Populate the return list with
  // all signatures.
  for (unsigned I = 0; I < NumSignatures; I++) {
    SmallVector<std::string, 2> Args;

    // Process a single signature.
    for (unsigned ArgNum = 0; ArgNum < Signature.size(); ArgNum++) {
      // For differently-sized GenTypes in a parameter list, the smaller
      // GenTypes just repeat, so index modulo the number of expanded types.
      size_t TypeIndex = I % ExpandedGenTypes[ArgNum].size();
      Args.push_back(ExpandedGenTypes[ArgNum][TypeIndex]);
    }
    Types.push_back(Args);
  }
}

void OpenCLBuiltinFileEmitterBase::emitExtensionSetup() {
  OS << R"(
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable
#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable
#pragma OPENCL EXTENSION cl_khr_mipmap_image_writes : enable
#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable

)";
}

std::string
OpenCLBuiltinFileEmitterBase::emitExtensionGuard(const Record *Builtin) {
  StringRef Extensions =
      Builtin->getValueAsDef("Extension")->getValueAsString("ExtName");
  if (Extensions.empty())
    return "";

  OS << "#if";

  SmallVector<StringRef, 2> ExtVec;
  Extensions.split(ExtVec, " ");
  bool isFirst = true;
  for (StringRef Ext : ExtVec) {
    if (!isFirst) {
      OS << " &&";
    }
    OS << " defined(" << Ext << ")";
    isFirst = false;
  }
  OS << "\n";

  return "#endif // Extension\n";
}

std::string
OpenCLBuiltinFileEmitterBase::emitVersionGuard(const Record *Builtin) {
  std::string OptionalEndif;
  auto PrintOpenCLVersion = [this](int Version) {
    OS << "CL_VERSION_" << (Version / 100) << "_" << ((Version % 100) / 10);
  };
  int MinVersion = Builtin->getValueAsDef("MinVersion")->getValueAsInt("ID");
  if (MinVersion != 100) {
    // OpenCL 1.0 is the default minimum version.
    OS << "#if __OPENCL_C_VERSION__ >= ";
    PrintOpenCLVersion(MinVersion);
    OS << "\n";
    OptionalEndif = "#endif // MinVersion\n" + OptionalEndif;
  }
  int MaxVersion = Builtin->getValueAsDef("MaxVersion")->getValueAsInt("ID");
  if (MaxVersion) {
    OS << "#if __OPENCL_C_VERSION__ < ";
    PrintOpenCLVersion(MaxVersion);
    OS << "\n";
    OptionalEndif = "#endif // MaxVersion\n" + OptionalEndif;
  }
  return OptionalEndif;
}

StringRef OpenCLBuiltinFileEmitterBase::emitTypeExtensionGuards(
    const SmallVectorImpl<std::string> &Signature) {
  SmallSet<StringRef, 2> ExtSet;

  // Iterate over all types to gather the set of required TypeExtensions.
  for (const auto &Ty : Signature) {
    StringRef TypeExt = TypeExtMap.lookup(Ty);
    if (!TypeExt.empty()) {
      // The TypeExtensions are space-separated in the .td file.
      SmallVector<StringRef, 2> ExtVec;
      TypeExt.split(ExtVec, " ");
      for (const auto Ext : ExtVec) {
        ExtSet.insert(Ext);
      }
    }
  }

  // Emit the #if only when at least one extension is required.
  if (ExtSet.empty())
    return "";

  OS << "#if ";
  bool isFirst = true;
  for (const auto Ext : ExtSet) {
    if (!isFirst)
      OS << " && ";
    OS << "defined(" << Ext << ")";
    isFirst = false;
  }
  OS << "\n";
  return "#endif // TypeExtension\n";
}

void OpenCLBuiltinTestEmitter::emit() {
  emitSourceFileHeader("OpenCL Builtin exhaustive testing", OS, Records);

  emitExtensionSetup();

  // Ensure each test has a unique name by numbering them.
  unsigned TestID = 0;

  // Iterate over all builtins.
  ArrayRef<const Record *> Builtins =
      Records.getAllDerivedDefinitions("Builtin");
  for (const auto *B : Builtins) {
    StringRef Name = B->getValueAsString("Name");

    SmallVector<SmallVector<std::string, 2>, 4> FTypes;
    expandTypesInSignature(B->getValueAsListOfDefs("Signature"), FTypes);

    OS << "// Test " << Name << "\n";

    std::string OptionalExtensionEndif = emitExtensionGuard(B);
    std::string OptionalVersionEndif = emitVersionGuard(B);

    for (const auto &Signature : FTypes) {
      StringRef OptionalTypeExtEndif = emitTypeExtensionGuards(Signature);

      // Emit function declaration.
      OS << Signature[0] << " test" << TestID++ << "_" << Name << "(";
      if (Signature.size() > 1) {
        for (unsigned I = 1; I < Signature.size(); I++) {
          if (I != 1)
            OS << ", ";
          OS << Signature[I] << " arg" << I;
        }
      }
      OS << ") {\n";

      // Emit function body.
      OS << "  ";
      if (Signature[0] != "void") {
        OS << "return ";
      }
      OS << Name << "(";
      for (unsigned I = 1; I < Signature.size(); I++) {
        if (I != 1)
          OS << ", ";
        OS << "arg" << I;
      }
      OS << ");\n";

      // End of function body.
      OS << "}\n";
      OS << OptionalTypeExtEndif;
    }

    OS << OptionalVersionEndif;
    OS << OptionalExtensionEndif;
  }
}

void OpenCLBuiltinHeaderEmitter::emit() {
  emitSourceFileHeader("OpenCL Builtin declarations", OS, Records);

  emitExtensionSetup();

  OS << R"(
#define __ovld __attribute__((overloadable))
#define __conv __attribute__((convergent))
#define __purefn __attribute__((pure))
#define __cnfn __attribute__((const))

)";

  // Iterate over all builtins; sort to follow order of definition in .td file.
  std::vector<const Record *> Builtins =
      Records.getAllDerivedDefinitions("Builtin");
  sort(Builtins, LessRecord());

  for (const auto *B : Builtins) {
    StringRef Name = B->getValueAsString("Name");

    std::string OptionalExtensionEndif = emitExtensionGuard(B);
    std::string OptionalVersionEndif = emitVersionGuard(B);

    SmallVector<SmallVector<std::string, 2>, 4> FTypes;
    expandTypesInSignature(B->getValueAsListOfDefs("Signature"), FTypes);

    for (const auto &Signature : FTypes) {
      StringRef OptionalTypeExtEndif = emitTypeExtensionGuards(Signature);

      // Emit function declaration.
      OS << Signature[0] << " __ovld ";
      if (B->getValueAsBit("IsConst"))
        OS << "__cnfn ";
      if (B->getValueAsBit("IsPure"))
        OS << "__purefn ";
      if (B->getValueAsBit("IsConv"))
        OS << "__conv ";

      OS << Name << "(";
      if (Signature.size() > 1) {
        for (unsigned I = 1; I < Signature.size(); I++) {
          if (I != 1)
            OS << ", ";
          OS << Signature[I];
        }
      }
      OS << ");\n";

      OS << OptionalTypeExtEndif;
    }

    OS << OptionalVersionEndif;
    OS << OptionalExtensionEndif;
  }

  OS << "\n// Disable any extensions we may have enabled previously.\n"
        "#pragma OPENCL EXTENSION all : disable\n";
}

void clang::EmitClangOpenCLBuiltins(const RecordKeeper &Records,
                                    raw_ostream &OS) {
  BuiltinNameEmitter NameChecker(Records, OS);
  NameChecker.Emit();
}

void clang::EmitClangOpenCLBuiltinHeader(const RecordKeeper &Records,
                                         raw_ostream &OS) {
  OpenCLBuiltinHeaderEmitter HeaderFileGenerator(Records, OS);
  HeaderFileGenerator.emit();
}

void clang::EmitClangOpenCLBuiltinTests(const RecordKeeper &Records,
                                        raw_ostream &OS) {
  OpenCLBuiltinTestEmitter TestFileGenerator(Records, OS);
  TestFileGenerator.emit();
}
