<commit_before>/*
 *  Copyright 2010-2011 Fabric Technologies Inc. All rights reserved.
 */
 
#include "Adapter.h"
#include "Context.h"
#include "IntegerAdapter.h"
#include "Manager.h"
#include "ModuleBuilder.h"
#include "FunctionBuilder.h"
#include "BasicBlockBuilder.h"
#include "OpTypes.h"
#include "OverloadNames.h"

#include <Fabric/Core/RT/Desc.h>
#include <Fabric/Core/RT/Impl.h>
#include <Fabric/Core/RT/Manager.h>

#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/Function.h>
#include <llvm/Intrinsics.h>

namespace Fabric
{
  namespace CG
  {
    Adapter::Adapter( RC::ConstHandle<Manager> const &manager, RC::ConstHandle<RT::Desc> const &desc, Flags flags )
      : m_manager( manager )
      , m_desc( desc )
      , m_flags( flags )
      , m_codeName( desc->getImpl()->getCodeName() )
    {
    }
    
    RT::ImplType Adapter::getType() const
    {
      return m_desc->getType();
    }

    RC::ConstHandle<Manager> Adapter::getManager() const
    {
      return m_manager.makeStrong();
    }
    
    RC::ConstHandle<RT::Manager> Adapter::getRTManager() const
    {
      return getManager()->getRTManager();
    }
    
    RC::ConstHandle<RT::Desc> Adapter::getDesc() const
    {
      return m_desc;
    }
  
    RC::ConstHandle<RT::Impl> Adapter::getImpl() const
    {
      return getDesc()->getImpl();
    }
  
    std::string const &Adapter::getUserName() const
    {
      return getDesc()->getName();
    }
    
    llvm::Value *Adapter::llvmCallMalloc( CG::BasicBlockBuilder &basicBlockBuilder, llvm::Value *size ) const
    {
      
      RC::ConstHandle< IntegerAdapter > integerAdapter = basicBlockBuilder.getManager()->getIntegerAdapter();

      std::vector< llvm::Type const * > argTypes;
      argTypes.push_back( integerAdapter->llvmRType( basicBlockBuilder.getContext() ) );
      llvm::FunctionType const *funcType = llvm::FunctionType::get( basicBlockBuilder->getInt8PtrTy(), argTypes, false );

      llvm::AttributeWithIndex AWI[1];
      AWI[0] = llvm::AttributeWithIndex::get( ~0u, llvm::Attribute::NoUnwind );
      llvm::AttrListPtr attrListPtr = llvm::AttrListPtr::get( AWI, 1 );

      llvm::Function *func = llvm::cast<llvm::Function>( basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "malloc", funcType, attrListPtr ) ); 
      
      return basicBlockBuilder->CreateCall( func, size );
    }
    
    llvm::Value *Adapter::llvmCallRealloc( CG::BasicBlockBuilder &basicBlockBuilder, llvm::Value *data, llvm::Value *newSize ) const
    {
      RC::ConstHandle< IntegerAdapter > integerAdapter = basicBlockBuilder.getManager()->getIntegerAdapter();

      std::vector< llvm::Type const * > argTypes;
      argTypes.push_back( basicBlockBuilder->getInt8PtrTy() );
      argTypes.push_back( integerAdapter->llvmRType( basicBlockBuilder.getContext() ) );
      llvm::FunctionType const *funcType = llvm::FunctionType::get( basicBlockBuilder->getInt8PtrTy(), argTypes, false );

      llvm::AttributeWithIndex AWI[1];
      AWI[0] = llvm::AttributeWithIndex::get( ~0u, llvm::Attribute::NoUnwind );
      llvm::AttrListPtr attrListPtr = llvm::AttrListPtr::get( AWI, 1 );

      llvm::Function *func = llvm::cast<llvm::Function>( basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "realloc", funcType, attrListPtr ) ); 
      
      return basicBlockBuilder->CreateCall2( func, data, newSize );
    }
    
    void Adapter::llvmCallFree( CG::BasicBlockBuilder &basicBlockBuilder, llvm::Value *data ) const
    {
      // RC::ConstHandle< IntegerAdapter > integerAdapter = basicBlockBuilder.getManager()->getIntegerAdapter();

      std::vector< llvm::Type const * > argTypes;
      argTypes.push_back( basicBlockBuilder->getInt8PtrTy() );
      llvm::FunctionType const *funcType = llvm::FunctionType::get( basicBlockBuilder->getVoidTy(), argTypes, false );

      llvm::AttributeWithIndex AWI[1];
      AWI[0] = llvm::AttributeWithIndex::get( ~0u, llvm::Attribute::NoUnwind );
      llvm::AttrListPtr attrListPtr = llvm::AttrListPtr::get( AWI, 1 );

      llvm::Function *func = llvm::cast<llvm::Function>( basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "free", funcType, attrListPtr ) ); 
      
      basicBlockBuilder->CreateCall( func, basicBlockBuilder->CreatePointerCast( data, basicBlockBuilder->getInt8PtrTy() ) );
    }
    
    void Adapter::llvmAssign( BasicBlockBuilder &basicBlockBuilder, llvm::Value *dstLValue, llvm::Value *srcRValue ) const
    {
      // [pzion 20110204] Start by looking for operator overload
      std::string name = methodOverloadName( assignOpMethodName( ASSIGN_OP ), this, this );
      RC::ConstHandle<FunctionSymbol> functionSymbol = basicBlockBuilder.maybeGetFunction( name );
      if ( functionSymbol )
      {
        ExprValue dstExprValue = ExprValue( this, USAGE_LVALUE, basicBlockBuilder.getContext(), dstLValue );
        ExprValue srcExprValue = ExprValue( this, USAGE_RVALUE, basicBlockBuilder.getContext(), srcRValue );
        functionSymbol->llvmCreateCall( basicBlockBuilder, dstExprValue, srcExprValue );
      }
      else llvmDefaultAssign( basicBlockBuilder, dstLValue, srcRValue );
    }

    llvm::Value *Adapter::llvmCast( BasicBlockBuilder &basicBlockBuilder, ExprValue exprValue ) const
    {
      if ( exprValue.getAdapter()->getDesc()->getImpl() == getDesc()->getImpl() )
      {
        switch ( exprValue.getUsage() )
        {
          case USAGE_RVALUE:
            return exprValue.getValue();
          case USAGE_LVALUE:
          {
            llvm::Value *rValue = llvmLValueToRValue( basicBlockBuilder, exprValue.getValue() );
            llvmRetain( basicBlockBuilder, rValue );
            return rValue;
          }
          default:
            FABRIC_ASSERT( false );
            return 0;
        }
      }
      else
      {
        std::string name = constructOverloadName( this, exprValue.getAdapter() );
        exprValue.getAdapter()->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
        RC::ConstHandle<FunctionSymbol> functionSymbol = basicBlockBuilder.maybeGetFunction( name );<commit_msg>issue-384: don't crash when attempting to convert a void expression<commit_after>/*
 *  Copyright 2010-2011 Fabric Technologies Inc. All rights reserved.
 */
 
#include "Adapter.h"
#include "Context.h"
#include "IntegerAdapter.h"
#include "Manager.h"
#include "ModuleBuilder.h"
#include "FunctionBuilder.h"
#include "BasicBlockBuilder.h"
#include "OpTypes.h"
#include "OverloadNames.h"

#include <Fabric/Core/RT/Desc.h>
#include <Fabric/Core/RT/Impl.h>
#include <Fabric/Core/RT/Manager.h>

#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/Function.h>
#include <llvm/Intrinsics.h>

namespace Fabric
{
  namespace CG
  {
    Adapter::Adapter( RC::ConstHandle<Manager> const &manager, RC::ConstHandle<RT::Desc> const &desc, Flags flags )
      : m_manager( manager )
      , m_desc( desc )
      , m_flags( flags )
      , m_codeName( desc->getImpl()->getCodeName() )
    {
    }
    
    RT::ImplType Adapter::getType() const
    {
      return m_desc->getType();
    }

    RC::ConstHandle<Manager> Adapter::getManager() const
    {
      return m_manager.makeStrong();
    }
    
    RC::ConstHandle<RT::Manager> Adapter::getRTManager() const
    {
      return getManager()->getRTManager();
    }
    
    RC::ConstHandle<RT::Desc> Adapter::getDesc() const
    {
      return m_desc;
    }
  
    RC::ConstHandle<RT::Impl> Adapter::getImpl() const
    {
      return getDesc()->getImpl();
    }
  
    std::string const &Adapter::getUserName() const
    {
      return getDesc()->getName();
    }
    
    llvm::Value *Adapter::llvmCallMalloc( CG::BasicBlockBuilder &basicBlockBuilder, llvm::Value *size ) const
    {
      
      RC::ConstHandle< IntegerAdapter > integerAdapter = basicBlockBuilder.getManager()->getIntegerAdapter();

      std::vector< llvm::Type const * > argTypes;
      argTypes.push_back( integerAdapter->llvmRType( basicBlockBuilder.getContext() ) );
      llvm::FunctionType const *funcType = llvm::FunctionType::get( basicBlockBuilder->getInt8PtrTy(), argTypes, false );

      llvm::AttributeWithIndex AWI[1];
      AWI[0] = llvm::AttributeWithIndex::get( ~0u, llvm::Attribute::NoUnwind );
      llvm::AttrListPtr attrListPtr = llvm::AttrListPtr::get( AWI, 1 );

      llvm::Function *func = llvm::cast<llvm::Function>( basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "malloc", funcType, attrListPtr ) ); 
      
      return basicBlockBuilder->CreateCall( func, size );
    }
    
    llvm::Value *Adapter::llvmCallRealloc( CG::BasicBlockBuilder &basicBlockBuilder, llvm::Value *data, llvm::Value *newSize ) const
    {
      RC::ConstHandle< IntegerAdapter > integerAdapter = basicBlockBuilder.getManager()->getIntegerAdapter();

      std::vector< llvm::Type const * > argTypes;
      argTypes.push_back( basicBlockBuilder->getInt8PtrTy() );
      argTypes.push_back( integerAdapter->llvmRType( basicBlockBuilder.getContext() ) );
      llvm::FunctionType const *funcType = llvm::FunctionType::get( basicBlockBuilder->getInt8PtrTy(), argTypes, false );

      llvm::AttributeWithIndex AWI[1];
      AWI[0] = llvm::AttributeWithIndex::get( ~0u, llvm::Attribute::NoUnwind );
      llvm::AttrListPtr attrListPtr = llvm::AttrListPtr::get( AWI, 1 );

      llvm::Function *func = llvm::cast<llvm::Function>( basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "realloc", funcType, attrListPtr ) ); 
      
      return basicBlockBuilder->CreateCall2( func, data, newSize );
    }
    
    void Adapter::llvmCallFree( CG::BasicBlockBuilder &basicBlockBuilder, llvm::Value *data ) const
    {
      // RC::ConstHandle< IntegerAdapter > integerAdapter = basicBlockBuilder.getManager()->getIntegerAdapter();

      std::vector< llvm::Type const * > argTypes;
      argTypes.push_back( basicBlockBuilder->getInt8PtrTy() );
      llvm::FunctionType const *funcType = llvm::FunctionType::get( basicBlockBuilder->getVoidTy(), argTypes, false );

      llvm::AttributeWithIndex AWI[1];
      AWI[0] = llvm::AttributeWithIndex::get( ~0u, llvm::Attribute::NoUnwind );
      llvm::AttrListPtr attrListPtr = llvm::AttrListPtr::get( AWI, 1 );

      llvm::Function *func = llvm::cast<llvm::Function>( basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "free", funcType, attrListPtr ) ); 
      
      basicBlockBuilder->CreateCall( func, basicBlockBuilder->CreatePointerCast( data, basicBlockBuilder->getInt8PtrTy() ) );
    }
    
    void Adapter::llvmAssign( BasicBlockBuilder &basicBlockBuilder, llvm::Value *dstLValue, llvm::Value *srcRValue ) const
    {
      // [pzion 20110204] Start by looking for operator overload
      std::string name = methodOverloadName( assignOpMethodName( ASSIGN_OP ), this, this );
      RC::ConstHandle<FunctionSymbol> functionSymbol = basicBlockBuilder.maybeGetFunction( name );
      if ( functionSymbol )
      {
        ExprValue dstExprValue = ExprValue( this, USAGE_LVALUE, basicBlockBuilder.getContext(), dstLValue );
        ExprValue srcExprValue = ExprValue( this, USAGE_RVALUE, basicBlockBuilder.getContext(), srcRValue );
        functionSymbol->llvmCreateCall( basicBlockBuilder, dstExprValue, srcExprValue );
      }
      else llvmDefaultAssign( basicBlockBuilder, dstLValue, srcRValue );
    }

    llvm::Value *Adapter::llvmCast( BasicBlockBuilder &basicBlockBuilder, ExprValue exprValue ) const
    {
      if ( !exprValue.getAdapter() )
        throw Exception( "function does not return a value" );
        
      if ( exprValue.getAdapter()->getDesc()->getImpl() == getDesc()->getImpl() )
      {
        switch ( exprValue.getUsage() )
        {
          case USAGE_RVALUE:
            return exprValue.getValue();
          case USAGE_LVALUE:
          {
            llvm::Value *rValue = llvmLValueToRValue( basicBlockBuilder, exprValue.getValue() );
            llvmRetain( basicBlockBuilder, rValue );
            return rValue;
          }
          default:
            FABRIC_ASSERT( false );
            return 0;
        }
      }
      else
      {
        std::string name = constructOverloadName( this, exprValue.getAdapter() );
        exprValue.getAdapter()->llvmCompileToModule( basicBlockBuilder.getModuleBuilder() );
        RC::ConstHandle<FunctionSymbol> functionSymbol = basicBlockBuilder.maybeGetFunction( name );
{'fraction_non_alphanumeric': 0.13027626995057928, 'fraction_numerical': 0.005914283399497691, 'mean_word_length': 3.7186544342507646, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 109, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3680420', 'n_tokens_mistral': 3663, 'n_tokens_neox': 3641, 'n_words': 693}