diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2019-09-06 03:54:44 -0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-09-06 12:54:44 +0200 |
commit | 32769c478bb15bb7b290992a85dbea702dbc1f95 (patch) | |
tree | 99174185f1254828da0a385ae958b189b428b4a6 | |
parent | 83975543154f03b7803c1cb86a27e9c99e445b50 (diff) | |
download | Nim-32769c478bb15bb7b290992a85dbea702dbc1f95.tar.gz |
exportc now mangles same as importc, fixes #10578 (#12144)
* fixes #10578 * add tests * add changelog * add {.exportcpp.}
-rw-r--r-- | changelog.md | 2 | ||||
-rw-r--r-- | compiler/ast.nim | 1 | ||||
-rw-r--r-- | compiler/cgen.nim | 3 | ||||
-rw-r--r-- | compiler/pragmas.nim | 69 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 4 | ||||
-rw-r--r-- | tests/cpp/mexportc.nim | 9 | ||||
-rw-r--r-- | tests/cpp/texportc.nim | 22 |
7 files changed, 76 insertions, 34 deletions
diff --git a/changelog.md b/changelog.md index f135fa585..5735dd033 100644 --- a/changelog.md +++ b/changelog.md @@ -31,6 +31,8 @@ type ``` +- `exportc` now uses C instead of C++ mangling with `nim cpp`, matching behavior of `importc`, see #10578 + Use the new `exportcpp` to mangle as C++ when using `nim cpp`. ### Breaking changes in the compiler diff --git a/compiler/ast.nim b/compiler/ast.nim index f3012cd8a..758cd7cfe 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -239,6 +239,7 @@ type sfForward, # symbol is forward declared sfImportc, # symbol is external; imported sfExportc, # symbol is exported (under a specified name) + sfMangleCpp, # mangle as cpp (combines with `sfExportc`) sfVolatile, # variable is volatile sfRegister, # variable should be placed in a register sfPure, # object is "pure" that means it has no type-information diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 6e79b2d7b..ba240a020 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1039,7 +1039,8 @@ proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} = result = (sfCompileToCpp in m.module.flags and sfCompileToCpp notin sym.getModule().flags and m.config.cmd != cmdCompileToCpp) or ( - sym.flags * {sfImportc, sfInfixCall, sfCompilerProc} == {sfImportc} and + sym.flags * {sfInfixCall, sfCompilerProc, sfMangleCpp} == {} and + sym.flags * {sfImportc, sfExportc} != {} and sym.magic == mNone and m.config.cmd == cmdCompileToCpp) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 6c70e4bad..a314277be 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -19,25 +19,27 @@ const LastCallConv* = wNoconv const - procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, + declPragmas = {wImportc, wImportObjC, wImportCpp, wExportc, wExportCpp, + wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed} + ## common pragmas for declarations, to a good approximation + procPragmas* = declPragmas + {FirstCallConv..LastCallConv, wMagic, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader, - wCompilerProc, wNonReloadable, wCore, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, - wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, - wAsmNoStackFrame, wError, wDiscardable, wNoInit, wCodegenDecl, + wCompilerProc, wNonReloadable, wCore, wProcVar, wVarargs, wCompileTime, wMerge, + wBorrow, wImportCompilerProc, wThread, + wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl, wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe, - wConstructor, wExportNims, wUsed, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy} + wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy} converterPragmas* = procPragmas - {wNoDestroy} methodPragmas* = procPragmas+{wBase}-{wImportCpp, wNoDestroy} templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty, wDelegator, wExportNims, wUsed, wPragma} - macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, - wNodecl, wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator, - wExportNims, wUsed} - iteratorPragmas* = {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, - wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern, - wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises, - wTags, wLocks, wGcSafe, wExportNims, wUsed} + macroPragmas* = declPragmas + {FirstCallConv..LastCallConv, + wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore, + wDiscardable, wGensym, wInject, wDelegator} + iteratorPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, + wMagic, wBorrow, + wDiscardable, wGensym, wInject, wRaises, + wTags, wLocks, wGcSafe} exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks, wBoundChecks, wOverflowChecks, wNilChecks, wStyleChecks, wAssertions, @@ -49,25 +51,25 @@ const wDeprecated, wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd, wPatterns, wTrMacros, wEffects, wNoForward, wReorder, wComputedGoto, - wInjectStmt, wDeprecated, wExperimental, wThis, wUsed} - lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, + wInjectStmt, wExperimental, wThis, wUsed} + lambdaPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader, - wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, - wRaises, wLocks, wTags, wGcSafe, wCodegenDecl} - typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, - wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wExtern, wShallow, - wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, + wThread, wAsmNoStackFrame, + wRaises, wLocks, wTags, wGcSafe, wCodegenDecl} - {wExportNims, wError, wUsed} # why exclude these? + typePragmas* = declPragmas + {wMagic, wAcyclic, + wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wShallow, + wIncompleteStruct, wByCopy, wByRef, wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, - wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wPackage} - fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed} - varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, - wMagic, wHeader, wDeprecated, wCompilerProc, wCore, wDynlib, wExtern, - wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, - wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims, wUsed, wCursor} - constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl, - wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject, wExportNims, - wIntDefine, wStrDefine, wBoolDefine, wUsed, wCompilerProc, wCore} + wBorrow, wGcSafe, wPartial, wExplain, wPackage} + fieldPragmas* = declPragmas + { + wGuard, wBitsize} - {wExportNims, wNodecl} # why exclude these? + varPragmas* = declPragmas + {wVolatile, wRegister, wThreadVar, + wMagic, wHeader, wCompilerProc, wCore, wDynlib, + wNoInit, wCompileTime, wGlobal, + wGensym, wInject, wCodegenDecl, wGuard, wGoto, wCursor} + constPragmas* = declPragmas + {wHeader, wMagic, + wGensym, wInject, + wIntDefine, wStrDefine, wBoolDefine, wCompilerProc, wCore} letPragmas* = varPragmas procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNoSideEffect, wThread, wRaises, wLocks, wTags, wGcSafe} @@ -775,8 +777,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, if {optStyleHint, optStyleError} * c.config.globalOptions != {}: checkPragmaUse(c.config, key.info, k, ident.s) case k - of wExportc: + of wExportc, wExportCpp: makeExternExport(c, sym, getOptionalStr(c, it, "$1"), it.info) + if k == wExportCpp: + if c.config.cmd != cmdCompileToCpp: + localError(c.config, it.info, "exportcpp requires `nim cpp`, got " & $c.config.cmd) + else: + incl(sym.flags, sfMangleCpp) incl(sym.flags, sfUsed) # avoid wrong hints of wImportc: let name = getOptionalStr(c, it, "$1") diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 62b26adf3..23c87ac39 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -42,7 +42,7 @@ type wImmediate, wConstructor, wDestructor, wDelegator, wOverride, wImportCpp, wImportObjC, wImportCompilerProc, - wImportc, wExportc, wExportNims, wIncompleteStruct, wRequiresInit, + wImportc, wExportc, wExportCpp, wExportNims, wIncompleteStruct, wRequiresInit, wAlign, wNodecl, wPure, wSideEffect, wHeader, wNoSideEffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib, wCompilerProc, wCore, wProcVar, wBase, wUsed, @@ -129,7 +129,7 @@ const "immediate", "constructor", "destructor", "delegator", "override", "importcpp", "importobjc", - "importcompilerproc", "importc", "exportc", "exportnims", + "importcompilerproc", "importc", "exportc", "exportcpp", "exportnims", "incompletestruct", "requiresinit", "align", "nodecl", "pure", "sideeffect", "header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib", diff --git a/tests/cpp/mexportc.nim b/tests/cpp/mexportc.nim new file mode 100644 index 000000000..dee51f157 --- /dev/null +++ b/tests/cpp/mexportc.nim @@ -0,0 +1,9 @@ +{.used.} # ideally, would not be needed + +var fun0 {.exportc.} = 10 +proc fun1() {.exportc.} = discard +proc fun2() {.exportc: "$1".} = discard +proc fun3() {.exportc: "fun3Bis".} = discard + +when defined cpp: + proc funx1() {.exportcpp.} = discard diff --git a/tests/cpp/texportc.nim b/tests/cpp/texportc.nim new file mode 100644 index 000000000..3a2fa8748 --- /dev/null +++ b/tests/cpp/texportc.nim @@ -0,0 +1,22 @@ +discard """ + targets: "c cpp" +""" + +var fun0 {.importc.}: int +proc fun1() {.importc.} +proc fun2() {.importc: "$1".} +proc fun3() {.importc: "fun3Bis".} + +when defined cpp: + # proc funx1() {.importcpp.} # this does not work yet + proc funx1() {.importc: "_Z5funx1v".} + +doAssert fun0 == 10 +fun1() +fun2() +fun3() + +when defined cpp: + funx1() + +import ./mexportc |