Пример #1
0
func (v *Codegen) declareFunctionDecl(n *parser.FunctionDecl) {
	mangledName := n.Function.MangledName(parser.MANGLE_ARK_UNSTABLE)
	function := v.curFile.LlvmModule.NamedFunction(mangledName)
	if !function.IsNil() {
		v.err("function `%s` already exists in module", n.Function.Name)
	} else {
		/*numOfParams := len(n.Function.Parameters)
		if n.Function.Type.Receiver != nil {
			numOfParams++
		}*/

		// find them attributes yo
		attrs := n.Function.Type.Attrs()
		cBinding := attrs.Contains("c")

		// create the function type
		funcType := v.functionTypeToLLVMType(n.Function.Type, false)

		functionName := mangledName
		if cBinding {
			functionName = n.Function.Name
		}

		// add that shit
		function = llvm.AddFunction(v.curFile.LlvmModule, functionName, funcType)

		if !cBinding && !n.IsPublic() {
			function.SetLinkage(nonPublicLinkage)
		}

		if ccAttr := attrs.Get("call_conv"); ccAttr != nil {
			// TODO: move value checking to parser?
			if callConv, ok := callConvTypes[ccAttr.Value]; ok {
				function.SetFunctionCallConv(callConv)
			} else {
				v.err("undefined calling convention `%s` for function `%s` wanted", ccAttr.Value, n.Function.Name)
			}
		}

		if inlineAttr := attrs.Get("inline"); inlineAttr != nil {
			function.AddFunctionAttr(inlineAttrType[inlineAttr.Value])
		}

		/*// do some magical shit for later
		for i := 0; i < numOfParams; i++ {
			funcParam := function.Param(i)
			funcParam.SetName(n.Function.Parameters[i].Variable.MangledName(parser.MANGLE_ARK_UNSTABLE))
		}*/
	}
}