public override void Visit(FunctionProtoAST functionProto) { var functionIden = _symTableManager.LookupFunctionInfo(_currentFileName, functionProto.Name, _currentScopeId, functionProto.GetFunctionType().ArgumentTypes); if (functionIden.valueRef.Pointer == IntPtr.Zero) { var fnType = IRTypesConverter.GetFunctionType(functionProto.GetFunctionType()); functionIden.valueRef = LLVM.AddFunction(_module, functionProto.Name, fnType); } _currentFunction = functionIden.valueRef; }
public TypeAST GetReturnType(FunctionCallAST functionCallAst) { List <TypeAST> argsType = null; if (functionCallAst.ExpressionList.Count != 0) { if (functionCallAst.argTypes == null) { argsType = new List <TypeAST>(); foreach (var expression in functionCallAst.ExpressionList) { expression.Accept(this); argsType.Add(_stateInfo.currentType); } functionCallAst.argTypes = argsType; } else { argsType = functionCallAst.argTypes; } } FunctionTypeAST functionType; var arrayFunctionCall = functionCallAst.Name as ArrayAccessAST; if (arrayFunctionCall != null) { var arrayType = GetArrayType(arrayFunctionCall); var accessDimensions = arrayFunctionCall.AccessExprList.Count; functionType = GetArrayContainedType(arrayType, accessDimensions) as FunctionTypeAST; string invalidArgsMessage = string.Format("Invalid function arguments expected '{0}' got '{1}'", string.Join(",", functionType.ArgumentTypes), argsType == null ? "no argument" : string.Join(",", argsType)); if (argsType != null && ((!functionType.IsVarArgsFn && functionType.ArgumentTypes.Count != argsType.Count) || (functionType.IsVarArgsFn && functionType.ArgumentTypes.Count > argsType.Count))) { throw new Exception(invalidArgsMessage); } if (argsType == null && functionType.ArgumentTypes.Count != 0) { throw new Exception(invalidArgsMessage); } for (var i = 0; i < functionType.ArgumentTypes.Count; i++) { if (functionType.ArgumentTypes[i].ToString() != argsType[i].ToString() && !functionType.ArgumentTypes[i].GetType().IsAssignableFrom(argsType[i].GetType())) { throw new Exception(invalidArgsMessage); } } } else { var functionCallInfo = _symTableManager. LookupFunctionInfo(_stateInfo.currentFile, functionCallAst.Name.ToString(), _stateInfo.scopeId, argsType); if (functionCallInfo == null) { throw new Exception(string.Format("Undefined function {0}({1})", functionCallAst.Name, argsType != null ? string.Join(",", argsType) : "")); } functionType = functionCallInfo.typeAST as FunctionTypeAST; } return(functionType.ReturnType); }