class Carbon::Concrete::Item::Function

A function definition. This contains all of the information needed to build a proper LLVM function. This is stored within an index and serialized as needed, in order to defer compilation. There are two main types of functions: “normal,” or “extern.” “Normal” functions have an actual definition (i.e. {Tacky::Function}), and are written in Ruby/Carbon. “Extern” functions do not have a definition; they map a Carbon function to a C/low-level function. Instead of a definition, they have a function name, that maps to the C/low-level function. This is normally specified with an `:extern` directive.

@api private @note

**This class is frozen upon initialization.**  This means that any
attempt to modify it will result in an error.  In most cases, the
attributes on this class will also be frozen, as well.

Attributes

definition[R]
return[R]

Public Class Methods

from(type) click to toggle source

(see Item::Base.from)

# File lib/carbon/concrete/item/function.rb, line 28
def self.from(type)
  {
    type: type,
    generics: type.generics,
    internal: type.function.name,
    parameters: type.function.parameters,
    definition: Tacky::Function.new(type.function.parameters)
  }
end
new(data) click to toggle source
# File lib/carbon/concrete/item/function.rb, line 38
def initialize(data)
  @type = data.fetch(:type)
  @internal = data.fetch(:internal) { @type.function.name }
  @parameters = data.fetch(:parameters) { @type.function.parameters }
  @definition = data.fetch(:definition)
  @generics = data.fetch(:generics) { @type.generics }
  @return = data.fetch(:return)
  @extern = data[:extern]
  @name = @type.to_s

  derive_dependencies
  deep_freeze!
end

Public Instance Methods

call(build, generics) click to toggle source

(see Base#call)

# File lib/carbon/concrete/item/function.rb, line 62
def call(build, generics)
  case @definition
  when Tacky::Function
    build_function_intern(build, generics)
  when ::String, ::Symbol
    build_function_extern(build, generics)
  else fail ArgumentError,
    "Unknown definition #{@definition.class}"
  end
end
define(index) click to toggle source
# File lib/carbon/concrete/item/function.rb, line 52
def define(index)
  if @definition.is_a?(::Proc)
    Function.new(Function.from(@type)
      .merge(definition: @definition.call(index), return: @return))
  else
    self
  end
end

Private Instance Methods

build_function_extern(build, generics) click to toggle source
# File lib/carbon/concrete/item/function.rb, line 85
def build_function_extern(build, generics)
  full = @type.sub(generics)
  params = @parameters
    .map { |p| build.fetch(p.sub(generics)).last }
  ret = build.fetch(@return.sub(generics)).last
  func = build.module.functions.add(@definition, params, ret)
  build.items[full] = [self, func]
end
build_function_intern(build, generics) click to toggle source
# File lib/carbon/concrete/item/function.rb, line 75
def build_function_intern(build, generics)
  full = @type.sub(generics)
  params = @parameters
    .map { |p| build.fetch(p.sub(generics)).last }
  ret = build.fetch(@return.sub(generics)).last
  func = build.module.functions.add(@extern || full, params, ret)
  @definition.call(func, build, generics)
  build.items[full] = [self, func]
end
derive_dependencies() click to toggle source

rubocop:enable Metrics/AbcSize

# File lib/carbon/concrete/item/function.rb, line 95
def derive_dependencies
  @dependencies = Set.new
  @dependencies << @return
  @dependencies.merge(@parameters)
  @dependencies.merge(@definition.dependencies) if \
    @definition.is_a?(Tacky::Function)
end