From 9d2a05f37c5b942acae05ba70f54657f2ae4b5ec Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 2 Aug 2018 21:21:30 +0200 Subject: [PATCH] better handling of builtin and extern C functions (ticket:5057) - check if the non fullyqualified name of the function is the same as the name of the external function - if the non fullyqualified name is not the same, generate the function and call the extern definition - fix definition of builtin integerMax and numBits Belonging to [master]: - OpenModelica/OMCompiler#2585 --- Compiler/FrontEnd/ModelicaBuiltin.mo | 4 ++-- Compiler/NFFrontEnd/NFModelicaBuiltin.mo | 4 ++-- Compiler/Script/CevalScriptBackend.mo | 5 ++++- Compiler/SimCode/SimCodeFunctionUtil.mo | 24 ++++++++++++++++-------- Compiler/Template/CodegenCFunctions.tpl | 17 ++++++++++------- 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/Compiler/FrontEnd/ModelicaBuiltin.mo b/Compiler/FrontEnd/ModelicaBuiltin.mo index b41c9c162c..20a83769e5 100644 --- a/Compiler/FrontEnd/ModelicaBuiltin.mo +++ b/Compiler/FrontEnd/ModelicaBuiltin.mo @@ -1021,11 +1021,11 @@ package Internal "Contains internal implementations, e.g. overloaded builtin fun package Architecture function numBits output Integer numBit; - external "builtin"; + external "builtin" numBit = architecture_numbits() annotation(Include="#define architecture_numbits() (8*sizeof(void*))"); end numBits; function integerMax output Integer max; - external "builtin"; + external "builtin" max = intMaxLit(); end integerMax; end Architecture; diff --git a/Compiler/NFFrontEnd/NFModelicaBuiltin.mo b/Compiler/NFFrontEnd/NFModelicaBuiltin.mo index 5e5a6aa672..fc74c3241c 100644 --- a/Compiler/NFFrontEnd/NFModelicaBuiltin.mo +++ b/Compiler/NFFrontEnd/NFModelicaBuiltin.mo @@ -1142,11 +1142,11 @@ package Internal "Contains internal implementations, e.g. overloaded builtin fun package Architecture function numBits output Integer numBit; - external "builtin"; + external "builtin" numBit = architecture_numbits() annotation(Include="#define architecture_numbits() (8*sizeof(void*))"); end numBits; function integerMax output Integer max; - external "builtin"; + external "builtin" max = intMaxLit(); end integerMax; end Architecture; diff --git a/Compiler/Script/CevalScriptBackend.mo b/Compiler/Script/CevalScriptBackend.mo index a7db1c3619..b5dc7cf8dd 100644 --- a/Compiler/Script/CevalScriptBackend.mo +++ b/Compiler/Script/CevalScriptBackend.mo @@ -5800,13 +5800,16 @@ algorithm Flags.setConfigBool(Flags.CHECK_MODEL, true); (_,Values.STRING(str)) = checkModel(FCore.emptyCache(), env, className, msg); Flags.setConfigBool(Flags.CHECK_MODEL, false); - (_,Values.STRING(str)) = checkModel(FCore.emptyCache(), env, className, msg); t2 = clock(); elapsedTime = t2 - t1; s = realString(elapsedTime); print (s + " seconds -> " + failOrSuccess(str) + "\n\t"); print (System.stringReplace(str, "\n", "\n\t")); print ("\n"); + print ("Error String:\n" + Print.getErrorString() + "\n"); + print ("Error Buffer:\n" + ErrorExt.printMessagesStr(false) + "\n"); + print ("# " + realString(elapsedTime) + " : " + Absyn.pathString(className) + "\n"); + print ("-------------------------------------------------------------------------\n"); checkAll(cache, env, rest, msg); then (); diff --git a/Compiler/SimCode/SimCodeFunctionUtil.mo b/Compiler/SimCode/SimCodeFunctionUtil.mo index 35ef64be69..3b41de803c 100644 --- a/Compiler/SimCode/SimCodeFunctionUtil.mo +++ b/Compiler/SimCode/SimCodeFunctionUtil.mo @@ -545,7 +545,7 @@ algorithm DAE.Function fel; list rest; list decls; - String name; + String name, fname; list includeDirs; Absyn.Path path; @@ -563,18 +563,26 @@ algorithm (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); then (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - case (_, DAE.FUNCTION(functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(language="builtin"))::_)::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) + case (_, (fel as DAE.FUNCTION(path = path, functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="builtin"))::_))::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) equation - // skip over builtin functions - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); + // skip over builtin functions @adrpo: we should skip ONLY IF THE NAME OF THE FUNCTION IS THE SAME AS THE NAME OF THE EXTERNAL FUNCTION! + fname = Absyn.pathString(Absyn.makeNotFullyQualified(path)); + b = stringEq(fname, name); + if not b then + (fn,_, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); + end if; + (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), rt, decls, includes, includeDirs, libs,libPaths); then (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - case (_, (fel as DAE.FUNCTION(functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="C"))::_))::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) + case (_, (fel as DAE.FUNCTION(path = path, functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="C"))::_))::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) equation - // skip over builtin functions - b = listMember(name, SCode.knownExternalCFunctions); - (fn,_, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); + // skip over known external C functions @adrpo: we should skip ONLY IF THE NAME OF THE FUNCTION IS THE SAME AS THE NAME OF THE EXTERNAL FUNCTION! + fname = Absyn.pathString(Absyn.makeNotFullyQualified(path)); + b = listMember(name, SCode.knownExternalCFunctions) and stringEq(fname, name); + if not b then + (fn,_, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); + end if; (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), rt, decls, includes, includeDirs, libs,libPaths); then (fns, rt_2, decls, includes, includeDirs, libs,libPaths); diff --git a/Compiler/Template/CodegenCFunctions.tpl b/Compiler/Template/CodegenCFunctions.tpl index b3702fd193..15ac909e1c 100644 --- a/Compiler/Template/CodegenCFunctions.tpl +++ b/Compiler/Template/CodegenCFunctions.tpl @@ -784,17 +784,16 @@ case func as EXTERNAL_FUNCTION(__) then let fn_name = extFunctionName(extName, language) let fargsStr = extFunDefArgs(extArgs, language) let fargsStrEscaped = '<%escapeCComments(fargsStr)%>' - let includesStr = includes |> i => i ;separator=", " + let isBuiltin = match language case "BUILTIN" then true end match /* * adrpo: * only declare the external function definition IF THERE WERE NO INCLUDES! - * i did not put includesStr string in the comment below as it might include - * entire files + * or if the function is not builtin */ - if includes then + if boolOr(boolNot(listEmpty(includes)), boolNot(stringEq(isBuiltin, ""))) then << /* - * The function has annotation(Include=...>) + * The function has annotation(Include=...>) or is builtin * the external function definition should be present * in one of these files and have this prototype: * extern <%extReturnType(extReturn)%> <%fn_name%>(<%fargsStrEscaped%>); @@ -823,17 +822,19 @@ end extFunDefDynamic; /* public */ template extFunctionName(String name, String language) "used in Compiler/Template/CodegenFMU.tpl" ::= match language + case "BUILTIN" case "C" then '<%name%>' case "FORTRAN 77" then '<%name%>_' - else error(sourceInfo(), 'Unsupport external language: <%language%>') + else error(sourceInfo(), 'Unsupported external language: <%language%>') end extFunctionName; template extFunDefArgs(list args, String language) ::= match language + case "BUILTIN" case "C" then (args |> arg => extFunDefArg(arg) ;separator=", ") case "FORTRAN 77" then (args |> arg => extFunDefArgF77(arg) ;separator=", ") - else error(sourceInfo(), 'Unsupport external language: <%language%>') + else error(sourceInfo(), 'Unsupported external language: <%language%>') end extFunDefArgs; template extReturnType(SimExtArg extArg) @@ -2111,8 +2112,10 @@ template extFunCall(Function fun, Text &preExp, Text &varDecls, Text &varInit, T match fun case EXTERNAL_FUNCTION(__) then match language + case "BUILTIN" case "C" then extFunCallC(fun, &preExp, &varDecls, &auxFunction) case "FORTRAN 77" then extFunCallF77(fun, &preExp, &varDecls, &varInit, &auxFunction) + else error(sourceInfo(), 'Unsupported external language: <%language%>') end extFunCall; template extFunCallC(Function fun, Text &preExp, Text &varDecls, Text &auxFunction)