/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * 
 * ExternLayer.h
 *
 *  Created on: 4/21/15
 *      Author: pgess <v.melnychenko@xreate.org>
 */

/**
 * \file    ExternLayer.h
 * \brief   An external C code interaction support
 */
#ifndef XREATE_EXTERNLAYER_H
#define XREATE_EXTERNLAYER_H

#include "llvmlayer.h"
#include <vector>
#include <string>
#include <map>
#include "ast.h"
#include "clang/AST/ASTContext.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/CodeGen/CodeGenABITypes.h"
#include "clang/Lex/PreprocessorOptions.h"

namespace clang{
class CodeGenerator;
}

namespace xreate{

/** \brief A wrapper over Clang */
class ExternLayer{
public:
    ExternLayer(LLVMLayer* llvm);
    void init(const AST* ast);

    llvm::Function* lookupFunction(const std::string& name);
    clang::QualType lookupType(const std::string& id);
    std::vector<std::string> getStructFields(const clang::QualType& ty);
    llvm::Type* toLLVMType(const clang::QualType& t);
    bool isPointer(const clang::QualType& t);
    bool isArrayType(const std::string& type);
    bool isRecordType(const std::string& type);

    static std::vector<std::string> fetchPackageFlags(const std::string& package);
    static std::vector<std::string> fetchPackageLibs(const std::string& package);

private:
    std::unique_ptr<clang::ASTUnit> ast;
    std::unique_ptr<clang::CodeGenerator> __codegen;
    std::unique_ptr<clang::CompilerInstance> __clang;
    LLVMLayer* __llvm;
    std::map<std::string, llvm::Function*> __functions;

    void loadLibraries(std::vector<std::string>&& libs);
};
}
#endif //XREATE_EXTERNLAYER_H
