/*===================== begin_copyright_notice ==================================

Copyright (c) 2017 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


======================= end_copyright_notice ==================================*/

#pragma once

#if defined (_WIN32)
#if defined (COMMON_CLANG_EXPORTS)
#define CC_DLL_EXPORT _declspec(dllexport)
#else
#define CC_DLL_EXPORT _declspec(dllimport)
#endif
#else
#define CC_DLL_EXPORT
#endif

namespace Intel { namespace OpenCL { namespace ClangFE {
    //
    // Type of the binary returned after compilation and/or link
    //
    enum IR_TYPE
    {
        IR_TYPE_UNKNOWN,
        IR_TYPE_EXECUTABLE,
        IR_TYPE_LIBRARY,
        IR_TYPE_COMPILED_OBJECT
    };

    //
    // Compilation results interface
    // Returned by Compile method
    //
    struct IOCLFEBinaryResult
    {
        // Returns the size in bytes of the IR buffer
        virtual size_t      GetIRSize() const = 0;
        // Returns the pointer to the IR buffer or NULL if no IR buffer is present
        virtual const void* GetIR() const = 0;
        // Returns the name of the program
        virtual const char* GetIRName() const = 0;
        // Returns the type of the resulted binary
        virtual IR_TYPE GetIRType() const = 0;
        // Returns the pointer to the compilation log string or NULL if not log was created
        virtual const char* GetErrorLog() const = 0;
        // Releases the result object
        virtual void        Release() = 0;
        protected:
        virtual             ~IOCLFEBinaryResult(){}
    };
}}}

//
//Verifies the given OpenCL application supplied compilation options
//Params:
//    pszOptions - compilation options string
//    pszUnknownOptions - optional outbound pointer to the space separated unrecognized options
//    uiUnknownOptionsSize - size of the pszUnknownOptions buffer
//Returns:
//    true if the options verification was succesfull, false otherwise
//
extern "C" CC_DLL_EXPORT bool CheckCompileOptions(
    // A string for compile options
    const char*     pszOptions,
    // buffer to get the list of unknown options
    char* pszUnknownOptions,
    // size of the buffer for unknown options
    size_t uiUnknownOptionsSize
    );

//
//Verifies the given OpenCL application supplied link options
//Params:
//    pszOptions - compilation options string
//    pszUnknownOptions - optional outbound pointer to the space separated unrecognized options
//    uiUnknownOptionsSize - size of the pszUnknownOptions buffer
//Returns:
//    true if the options verification was succesfull, false otherwise
//
extern "C" CC_DLL_EXPORT bool CheckLinkOptions(
    // A string for compile options
    const char*     pszOptions,
    // buffer to get the list of unknown options
    char* pszUnknownOptions,
    // size of the buffer for unknown options
    size_t uiUnknownOptionsSize
    );

//
//Compiles the given OpenCL program to the LLVM IR
//Params:
//    pProgramSource - OpenCL source program to compile
//    pInputHeaders - array of the header buffers
//    uiNumInputHeader - size of the pInputHeaders array
//    pszInputHeadersNames - array of the headers names
//    pPCHBuffer - optional pointer to the pch buffer
//    uiPCHBufferSize - size of the pch buffer
//    pszOptions - OpenCL application supplied options
//    pszOptionsEx - optional extra options string usually supplied by runtime
//    pszDeviceSupportedExtentions - space separated list of the supported OpenCL extensions string
//    pszOpenCLVer - OpenCL version string - "120" for OpenCL 1.2, "200" for OpenCL 2.0, ...
//    pBinaryResult - optional outbound pointer to the compilation results
//Returns:
//    Compilation Result as int:  0 - success, error otherwise.
//
extern "C" CC_DLL_EXPORT int Compile(
    // A pointer to main program's source (null terminated string)
    const char*     pszProgramSource,
    // array of additional input headers to be passed in memory (each null terminated)
    const char**    pInputHeaders,
    // the number of input headers in pInputHeaders
    unsigned int    uiNumInputHeaders,
    // array of input headers names corresponding to pInputHeaders
    const char**    pInputHeadersNames,
    // optional pointer to the pch buffer
    const char*     pPCHBuffer,
    // size of the pch buffer
    size_t          uiPCHBufferSize,
    // OpenCL application supplied options
    const char*     pszOptions,
    // optional extra options string usually supplied by runtime
    const char*     pszOptionsEx,
    // OpenCL version string - "120" for OpenCL 1.2, "200" for OpenCL 2.0, ...
    const char*     pszOpenCLVer,
    // optional outbound pointer to the compilation results
    Intel::OpenCL::ClangFE::IOCLFEBinaryResult** pBinaryResult
    );

//
//Links the given OpenCL binaries
//Params:
//    pInputHeaders - array of the header buffers
//    uiNumInputHeader - size of the pInputHeaders array
//    pszInputHeadersNames - array of the headers names
//    pPCHBuffer - optional pointer to the pch buffer
//    uiPCHBufferSize - size of the pch buffer
//    pszOptions - OpenCL application supplied options
//    pszOptionsEx - optional extra options string usually supplied by runtime
//    pszDeviceSupportedExtentions - space separated list of the supported OpenCL extensions string
//    pszOpenCLVer - OpenCL version string - "120" for OpenCL 1.2, "200" for OpenCL 2.0, ...
//    pBinaryResult - optional outbound pointer to the compilation results
//Returns:
//    Link Result as int:  0 - success, error otherwise.
//
extern "C" CC_DLL_EXPORT int Link(
    // array of additional input headers to be passed in memory
    const void**    pInputBinaries,
    // the number of input binaries
    unsigned int    uiNumBinaries,
    // the size in bytes of each binary
    const size_t*   puiBinariesSizes,
    // OpenCL application supplied options
    const char*     pszOptions,
    // optional outbound pointer to the compilation results
    Intel::OpenCL::ClangFE::IOCLFEBinaryResult** pBinaryResult
    );
