CG::ExprValue ConstFloat::buildExprValue( CG::BasicBlockBuilder &basicBlockBuilder, CG::Usage usage, std::string const &lValueErrorDesc ) const { if ( usage == CG::USAGE_LVALUE ) throw Exception( "constants cannot be used as l-values" ); RC::ConstHandle<CG::FloatAdapter> floatAdapter = basicBlockBuilder.getManager()->getFloat64Adapter(); floatAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); double value = Util::parseDouble( m_valueString ); return CG::ExprValue( floatAdapter, CG::USAGE_RVALUE, basicBlockBuilder.getContext(), floatAdapter->llvmConst( basicBlockBuilder.getContext(), value ) ); }
CG::ExprValue ConstString::buildExprValue( CG::BasicBlockBuilder &basicBlockBuilder, CG::Usage usage, std::string const &lValueErrorDesc ) const { if ( usage == CG::USAGE_LVALUE ) throw Exception( "constants cannot be used as l-values" ); std::string unquotedValue; try { unquotedValue = Util::parseQuotedString( m_value ); } catch ( Exception e ) { throw CG::Error( getLocation(), e.getDesc() + "(" + m_value + ")" ); } RC::ConstHandle<CG::ConstStringAdapter> constStringAdapter = basicBlockBuilder.getManager()->getConstStringAdapter(); constStringAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); RC::ConstHandle<CG::StringAdapter> stringAdapter = basicBlockBuilder.getManager()->getStringAdapter(); stringAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); return CG::ExprValue( constStringAdapter, CG::USAGE_RVALUE, basicBlockBuilder.getContext(), constStringAdapter->llvmConst( basicBlockBuilder, unquotedValue.data(), unquotedValue.length() ) ).castTo( basicBlockBuilder, stringAdapter ); }
CG::ExprType MethodOp::getExprType( CG::BasicBlockBuilder &basicBlockBuilder ) const { RC::ConstHandle<CG::Adapter> adapter = getFunction( basicBlockBuilder )->getReturnInfo().getAdapter(); if ( adapter ) { adapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); return CG::ExprType( adapter, CG::USAGE_RVALUE ); } else return CG::ExprType(); }
CG::ExprType IndexOp::getExprType( CG::BasicBlockBuilder &basicBlockBuilder ) const { CG::ExprType exprType = m_expr->getExprType( basicBlockBuilder ); exprType.getAdapter()->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); if ( RT::isArray( exprType.getAdapter()->getType() ) ) { RC::ConstHandle<CG::ArrayAdapter> arrayType = RC::ConstHandle<CG::ArrayAdapter>::StaticCast( exprType.getAdapter() ); RC::ConstHandle<CG::Adapter> memberAdapter = arrayType->getMemberAdapter(); memberAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); return CG::ExprType( memberAdapter, exprType.getUsage() ); } else if ( RT::isDict( exprType.getAdapter()->getType() ) ) { RC::ConstHandle<CG::DictAdapter> dictType = RC::ConstHandle<CG::DictAdapter>::StaticCast( exprType.getAdapter() ); RC::ConstHandle<CG::Adapter> valueAdapter = dictType->getValueAdapter(); valueAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); return CG::ExprType( valueAdapter, exprType.getUsage() ); } else throw Exception( "only arrays and dictionaries can be indexed" ); }
void Report::llvmCompileToBuilder( CG::BasicBlockBuilder &basicBlockBuilder, CG::Diagnostics &diagnostics ) const { RC::ConstHandle< CG::StringAdapter > stringAdapter = basicBlockBuilder.getManager()->getStringAdapter(); stringAdapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); try { CG::Scope subScope( basicBlockBuilder.getScope() ); CG::BasicBlockBuilder subBBB( basicBlockBuilder, subScope ); CG::ExprValue exprExprValue = m_expr->buildExprValue( subBBB, CG::USAGE_RVALUE, "cannot be an l-value" ); llvm::Value *stringRValue = stringAdapter->llvmCast( subBBB, exprExprValue ); stringAdapter->llvmReport( subBBB, stringRValue ); subScope.llvmUnwind( subBBB ); } catch ( CG::Error e ) { addError( diagnostics, e ); } catch ( Exception e ) { addError( diagnostics, e ); } }
CG::ExprType ConstString::getExprType( CG::BasicBlockBuilder &basicBlockBuilder ) const { RC::ConstHandle<CG::Adapter> adapter = basicBlockBuilder.getManager()->getStringAdapter(); adapter->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() ); return CG::ExprType( adapter, CG::USAGE_RVALUE ); }
void ArrayProducerAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const { if ( moduleBuilder.haveCompiledToModule( getCodeName() ) ) return; RC::Handle<Context> context = moduleBuilder.getContext(); m_elementAdapter->llvmCompileToModule( moduleBuilder ); m_elementVariableArrayAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<BooleanAdapter> booleanAdapter = getManager()->getBooleanAdapter(); booleanAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter(); sizeAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter(); stringAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<ConstStringAdapter> constStringAdapter = getManager()->getConstStringAdapter(); constStringAdapter->llvmCompileToModule( moduleBuilder ); static const bool buildFunctions = true; { ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost ); if ( buildFunctions ) { llvm::Value *stringLValue = functionBuilder[0]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); std::string name = getUserName(); ExprValue exprValue( constStringAdapter, USAGE_RVALUE, context, constStringAdapter->llvmConst( basicBlockBuilder, name.data(), name.length() ) ); llvm::Value *stringRValue = stringAdapter->llvmCast( basicBlockBuilder, exprValue ); stringAdapter->llvmAssign( basicBlockBuilder, stringLValue, stringRValue ); stringAdapter->llvmDispose( basicBlockBuilder, stringRValue ); basicBlockBuilder->CreateRetVoid(); } } { ConstructorBuilder functionBuilder( moduleBuilder, booleanAdapter, this, ConstructorBuilder::HighCost ); if ( buildFunctions ) { llvm::Value *booleanLValue = functionBuilder[0]; llvm::Value *rValue = functionBuilder[1]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); llvm::Value *arrayProducerRValue = basicBlockBuilder->CreateLoad( rValue ); basicBlockBuilder->CreateStore( basicBlockBuilder->CreateIsNotNull( arrayProducerRValue ), booleanLValue ); basicBlockBuilder->CreateRetVoid(); } } { MethodBuilder functionBuilder( moduleBuilder, sizeAdapter, this, USAGE_RVALUE, "getCount" ); if ( buildFunctions ) { BasicBlockBuilder basicBlockBuilder( functionBuilder ); llvm::Value *rValue = functionBuilder[0]; llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" ); basicBlockBuilder->SetInsertPoint( entryBB ); basicBlockBuilder->CreateRet( llvmGetCount( basicBlockBuilder, rValue ) ); } } { MethodBuilder functionBuilder( moduleBuilder, m_elementVariableArrayAdapter, this, USAGE_RVALUE, "produce" ); if ( buildFunctions ) { BasicBlockBuilder basicBlockBuilder( functionBuilder ); llvm::Value *rValue = functionBuilder[0]; llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" ); basicBlockBuilder->SetInsertPoint( entryBB ); llvmProduce0( basicBlockBuilder, rValue, functionBuilder.getScope().llvmGetReturnLValue() ); basicBlockBuilder->CreateRetVoid(); } } { MethodBuilder functionBuilder( moduleBuilder, m_elementAdapter, this, USAGE_RVALUE, "produce", "index", sizeAdapter, USAGE_RVALUE ); if ( buildFunctions ) { BasicBlockBuilder basicBlockBuilder( functionBuilder ); llvm::Value *rValue = functionBuilder[0]; llvm::Value *indexRValue = functionBuilder[1]; llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" ); basicBlockBuilder->SetInsertPoint( entryBB ); CG::FunctionScope &functionScope = functionBuilder.getScope(); functionScope.llvmPrepareReturnLValue( basicBlockBuilder ); llvmProduce1( basicBlockBuilder, rValue, indexRValue, functionScope.llvmGetReturnLValue() ); if ( functionScope.getReturnInfo().usesReturnLValue() ) basicBlockBuilder->CreateRetVoid(); else basicBlockBuilder->CreateRet( basicBlockBuilder->CreateLoad( functionScope.llvmGetReturnLValue() ) ); } } { MethodBuilder functionBuilder( moduleBuilder, m_elementVariableArrayAdapter, this, USAGE_RVALUE, "produce", "index", sizeAdapter, USAGE_RVALUE, "count", sizeAdapter, USAGE_RVALUE ); if ( buildFunctions ) { BasicBlockBuilder basicBlockBuilder( functionBuilder ); llvm::Value *rValue = functionBuilder[0]; llvm::Value *indexRValue = functionBuilder[1]; llvm::Value *countRValue = functionBuilder[2]; llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" ); basicBlockBuilder->SetInsertPoint( entryBB ); llvmProduce2( basicBlockBuilder, rValue, indexRValue, countRValue, functionBuilder.getScope().llvmGetReturnLValue() ); basicBlockBuilder->CreateRetVoid(); } } { MethodBuilder functionBuilder( moduleBuilder, 0, this, USAGE_RVALUE, "flush" ); if ( buildFunctions ) { BasicBlockBuilder basicBlockBuilder( functionBuilder ); llvm::Value *rValue = functionBuilder[0]; llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" ); basicBlockBuilder->SetInsertPoint( entryBB ); llvmFlush( basicBlockBuilder, rValue ); basicBlockBuilder->CreateRetVoid(); } } }
void OpaqueAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const { if ( moduleBuilder.haveCompiledToModule( getCodeName() ) ) return; RC::Handle<Context> context = moduleBuilder.getContext(); RC::ConstHandle<BooleanAdapter> booleanAdapter = getManager()->getBooleanAdapter(); booleanAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter(); sizeAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter(); stringAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<OpaqueAdapter> dataAdapter = getManager()->getDataAdapter(); dataAdapter->llvmCompileToModule( moduleBuilder ); static const bool buildFunctions = true; { ConstructorBuilder functionBuilder( moduleBuilder, booleanAdapter, this, ConstructorBuilder::HighCost ); if ( buildFunctions ) { llvm::Value *booleanLValue = functionBuilder[0]; llvm::Value *opaqueRValue = functionBuilder[1]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); llvm::Value *booleanRValue = basicBlockBuilder->CreateIsNotNull( opaqueRValue ); booleanAdapter->llvmAssign( basicBlockBuilder, booleanLValue, booleanRValue ); basicBlockBuilder->CreateRetVoid(); } } { ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost ); if ( buildFunctions ) { llvm::Value *stringLValue = functionBuilder[0]; llvm::Value *opaqueRValue = functionBuilder[1]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); llvm::Value *opaqueLValue = llvmRValueToLValue( basicBlockBuilder, opaqueRValue ); stringAdapter->llvmCallCast( basicBlockBuilder, this, opaqueLValue, stringLValue ); basicBlockBuilder->CreateRetVoid(); } } { MethodBuilder functionBuilder( moduleBuilder, sizeAdapter, this, USAGE_RVALUE, "dataSize" ); if ( buildFunctions ) { BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); llvm::Value *dataSizeRValue = sizeAdapter->llvmConst( context, getDesc()->getAllocSize() ); basicBlockBuilder->CreateRet( dataSizeRValue ); } } { MethodBuilder functionBuilder( moduleBuilder, dataAdapter, this, USAGE_LVALUE, "data" ); if ( buildFunctions ) { llvm::Value *thisLValue = functionBuilder[0]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); basicBlockBuilder->CreateRet( basicBlockBuilder->CreatePointerCast( thisLValue, dataAdapter->llvmRType( context ) ) ); } } }
void StructAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const { if ( moduleBuilder.haveCompiledToModule( getCodeName() ) ) return; RC::Handle<Context> context = moduleBuilder.getContext(); RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter(); stringAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter(); sizeAdapter->llvmCompileToModule( moduleBuilder ); RC::ConstHandle<OpaqueAdapter> dataAdapter = getManager()->getDataAdapter(); dataAdapter->llvmCompileToModule( moduleBuilder ); for ( MemberAdaptorVector::const_iterator it=m_memberAdapters.begin(); it!=m_memberAdapters.end(); ++it ) (*it)->llvmCompileToModule( moduleBuilder ); static const bool buildFunctions = true; if ( !m_isShallow ) { { InternalFunctionBuilder functionBuilder( moduleBuilder, 0, "__" + getCodeName() + "__DefaultAssign", "dst", this, USAGE_LVALUE, "src", this, USAGE_RVALUE, 0 ); if ( buildFunctions ) { llvm::Value *dstLValue = functionBuilder[0]; llvm::Value *srcRValue = functionBuilder[1]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); for ( size_t i=0; i<getNumMembers(); ++i ) { RC::ConstHandle<Adapter> const &memberAdapter = m_memberAdapters[i]; llvm::Value *dstMemberLValue = basicBlockBuilder->CreateConstGEP2_32( dstLValue, 0, i ); llvm::Value *srcMemberLValue = basicBlockBuilder->CreateConstGEP2_32( srcRValue, 0, i ); llvm::Value *srcMemberRValue = memberAdapter->llvmLValueToRValue( basicBlockBuilder, srcMemberLValue ); memberAdapter->llvmAssign( basicBlockBuilder, dstMemberLValue, srcMemberRValue ); } basicBlockBuilder->CreateRetVoid(); } } } { ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost ); if ( buildFunctions ) { llvm::Value *stringLValue = functionBuilder[0]; llvm::Value *structRValue = functionBuilder[1]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); llvm::Value *structLValue = llvmRValueToLValue( basicBlockBuilder, structRValue ); stringAdapter->llvmCallCast( basicBlockBuilder, this, structLValue, stringLValue ); basicBlockBuilder->CreateRetVoid(); } } if ( getDesc()->isShallow() ) { { MethodBuilder functionBuilder( moduleBuilder, sizeAdapter, this, USAGE_RVALUE, "dataSize" ); if ( buildFunctions ) { BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); llvm::Value *dataSizeRValue = llvm::ConstantInt::get( sizeAdapter->llvmRType( context ), getDesc()->getAllocSize() ); basicBlockBuilder->CreateRet( dataSizeRValue ); } } { MethodBuilder functionBuilder( moduleBuilder, dataAdapter, this, USAGE_LVALUE, "data" ); if ( buildFunctions ) { llvm::Value *thisLValue = functionBuilder[0]; BasicBlockBuilder basicBlockBuilder( functionBuilder ); basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) ); basicBlockBuilder->CreateRet( basicBlockBuilder->CreatePointerCast( thisLValue, dataAdapter->llvmRType( context ) ) ); } } } }