CG::ExprValue CreateConstValue::buildExprValue( CG::BasicBlockBuilder &basicBlockBuilder, CG::Usage usage, std::string const &lValueErrorDesc ) const { if ( usage == CG::USAGE_LVALUE ) throw Exception( "cannot be used as l-values" ); CG::ExprType childExprType = m_child->getExprType( basicBlockBuilder ); RC::ConstHandle<CG::ValueProducerAdapter> valueProducerAdapter = basicBlockBuilder.getManager()->getValueProducerOf( childExprType.getAdapter() ); RC::Handle<CG::Context> context = basicBlockBuilder.getContext(); llvm::LLVMContext &llvmContext = context->getLLVMContext(); std::vector<llvm::Type const *> argTypes; argTypes.push_back( llvm::Type::getInt8PtrTy( llvmContext ) ); argTypes.push_back( llvm::Type::getInt8PtrTy( llvmContext ) ); argTypes.push_back( valueProducerAdapter->llvmLType( context ) ); llvm::FunctionType const *funcType = llvm::FunctionType::get( llvm::Type::getVoidTy( llvmContext ), argTypes, false ); llvm::Constant *func = basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "__MR_CreateConstValue", funcType ); CG::ExprValue childExprRValue = m_child->buildExprValue( basicBlockBuilder, CG::USAGE_RVALUE, lValueErrorDesc ); llvm::Value *childExprLValue = childExprType.getAdapter()->llvmRValueToLValue( basicBlockBuilder, childExprRValue.getValue() ); llvm::Value *resultLValue = valueProducerAdapter->llvmAlloca( basicBlockBuilder, "result" ); valueProducerAdapter->llvmInit( basicBlockBuilder, resultLValue ); basicBlockBuilder.getScope().put( CG::VariableSymbol::Create( CG::ExprValue( valueProducerAdapter, CG::USAGE_LVALUE, context, resultLValue ) ) ); basicBlockBuilder->CreateCall3( func, valueProducerAdapter->llvmAdapterPtr( basicBlockBuilder ), basicBlockBuilder->CreatePointerCast( childExprLValue, llvm::Type::getInt8PtrTy( llvmContext ) ), resultLValue ); return CG::ExprValue( valueProducerAdapter, CG::USAGE_RVALUE, context, valueProducerAdapter->llvmLValueToRValue( basicBlockBuilder, resultLValue ) ); }
void ArrayProducerAdapter::llvmProduce0( CG::BasicBlockBuilder &basicBlockBuilder, llvm::Value *arrayProducerRValue, llvm::Value *dstLValue ) const { RC::Handle<Context> context = basicBlockBuilder.getContext(); std::vector<llvm::Type *> argTypes; argTypes.push_back( basicBlockBuilder->getInt8PtrTy() ); argTypes.push_back( llvmRType( context ) ); argTypes.push_back( m_elementVariableArrayAdapter->llvmLType( context ) ); llvm::FunctionType *funcType = llvm::FunctionType::get( llvm::Type::getVoidTy( context->getLLVMContext() ), argTypes, false ); llvm::Constant *func = basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "__"+getCodeName()+"__Produce0", funcType ); basicBlockBuilder->CreateCall3( func, llvmAdapterPtr( basicBlockBuilder ), arrayProducerRValue, dstLValue ); }