
/*
 * versions.cpp
 *
 * Author: pgess <v.melnychenko@xreate.org>
 * Created on January 21, 2017, 1:24 PM
 */

typename std::list<Symbol> VersionInferiorsList;

template<class Parent>
class VersionsScopeDecorator: public Parent{
    llvm::Value*
    compileSymbol(const Symbol& s, std::string hintSymbol=""){
        if (Attachments::exists<VersionInferiorsList>(s)){
            const VersionInferiorsList& symbolsInf= Attachments::get<VersionInferiorsList>(s);

            for (cont Symbol& inf: symbolsInf){
                Parent::compileSymbol(inf);
            }
        }

        return Parent::compileSymbol(s, hintSymbol);
    }

llvm::Value*
process(const Expression& expr, const std::string& hintVarDecl){
    case Operator::CALL_INTRINSIC: {
        enum INRINSIC{INIT, COPY};
        const llvm::IntegerType* tyInt = llvm::Type::getInt32Ty(llvm::getGlobalContext());
        const llvm::ConstantInt* constOne = llvm::ConstantInt::get(tyInt, 1, false);
        const ExpandedType& typSymbol = pass->man->root->expandType(expr.type);

        INTRINSIC op = (INTRINSIC) expr.getValueDouble();

        switch (op){
            case INIT: {
                llvm::Type* typSymbolRaw = l.toLLVMType(typSymbol);
                llvm::Value* storage = l.builder.CreateAlloca(typSymbolRaw, constOne, hintVarDecl);

                return storage;
            }

            case COPY: {
                llvm::Type* typSymbolRaw = l.toLLVMType(typSymbol);
                llvm::value* valueOriginal = process(expr.getOperands()[0], hintVarDecl);
                llvm::Value* storage = l.builder.CreateAlloca(typSymbolRaw, constOne, hintVarDecl);
                llvm::Value* valueCopy = l.builder.CreateStore(valueOriginal, storage);

                return valueCopy;
            }
        }
        return;
    }
}
};