diff options
-rw-r--r-- | changelog.md | 4 | ||||
-rw-r--r-- | compiler/cgen.nim | 15 | ||||
-rw-r--r-- | compiler/commands.nim | 5 | ||||
-rw-r--r-- | compiler/extccomp.nim | 10 | ||||
-rw-r--r-- | compiler/options.nim | 1 | ||||
-rw-r--r-- | doc/advopt.txt | 1 | ||||
-rw-r--r-- | lib/nimbase.h | 13 | ||||
-rw-r--r-- | lib/system/atomics.nim | 2 |
8 files changed, 44 insertions, 7 deletions
diff --git a/changelog.md b/changelog.md index 6edcb5b56..20ea58b08 100644 --- a/changelog.md +++ b/changelog.md @@ -79,6 +79,10 @@ target. To use it, compile your code with `--hotCodeReloading:on` and use a helper library such as LiveReload or BrowserSync. +- A new compiler option `--cppCompileToNamespace` puts the generated C++ code + into the namespace "Nim" in order to avoid naming conflicts with existing + C++ code. This is done for all Nim code - internal and exported. + - Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual machine. diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 78847c3b8..4d3cabd3a 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -676,6 +676,12 @@ proc generateHeaders(m: BModule) = add(m.s[cfsHeaders], "#undef powerpc" & tnl) add(m.s[cfsHeaders], "#undef unix" & tnl) +proc openNamespaceNim(): Rope = + result.add("namespace Nim {" & tnl) + +proc closeNamespaceNim(): Rope = + result.add("}" & tnl) + proc closureSetup(p: BProc, prc: PSym) = if tfCapturesEnv notin prc.typ.flags: return # prc.ast[paramsPos].last contains the type we're after: @@ -918,6 +924,7 @@ proc addIntTypes(result: var Rope) {.inline.} = addf(result, "#define NIM_NEW_MANGLING_RULES" & tnl & "#define NIM_INTBITS $1" & tnl, [ platform.CPU[targetCPU].intSize.rope]) + if useNimNamespace : result.add("#define USE_NIM_NAMESPACE" & tnl) proc getCopyright(cfile: Cfile): Rope = if optCompileOnly in gGlobalOptions: @@ -1083,7 +1090,11 @@ proc genMainProc(m: BModule) = appcg(m, m.s[cfsProcs], nimMain, [m.g.mainModInit, initStackBottomCall, rope(m.labels)]) if optNoMain notin gGlobalOptions: + if useNimNamespace: + m.s[cfsProcs].add closeNamespaceNim() & "using namespace Nim;" & tnl + appcg(m, m.s[cfsProcs], otherMain, []) + if useNimNamespace: m.s[cfsProcs].add openNamespaceNim() proc getSomeInitName(m: PSym, suffix: string): Rope = assert m.kind == skModule @@ -1191,7 +1202,9 @@ proc genModule(m: BModule, cfile: Cfile): Rope = add(result, genSectionStart(i)) add(result, m.s[i]) add(result, genSectionEnd(i)) + if useNimNamespace and i == cfsHeaders: result.add openNamespaceNim() add(result, m.s[cfsInitProc]) + if useNimNamespace: result.add closeNamespaceNim() proc newPreInitProc(m: BModule): BProc = result = newProc(nil, m) @@ -1330,11 +1343,13 @@ proc writeHeader(m: BModule) = add(result, genSectionStart(i)) add(result, m.s[i]) add(result, genSectionEnd(i)) + if useNimNamespace and i == cfsHeaders: result.add openNamespaceNim() add(result, m.s[cfsInitProc]) if optGenDynLib in gGlobalOptions: result.add("N_LIB_IMPORT ") result.addf("N_CDECL(void, NimMain)(void);$n", []) + if useNimNamespace: result.add closeNamespaceNim() result.addf("#endif /* $1 */$n", [guard]) writeRope(result, m.filename) diff --git a/compiler/commands.nim b/compiler/commands.nim index 20727966b..820cb7e1a 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -698,6 +698,11 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; expectNoArg(switch, arg, pass, info) newDestructors = true defineSymbol("nimNewRuntime") + of "cppcompiletonamespace": + expectNoArg(switch, arg, pass, info) + useNimNamespace = true + defineSymbol("cppCompileToNamespace") + else: if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg) else: invalidCmdLineOption(pass, switch, info) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 8b5a3bf3d..f9b18a335 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -176,10 +176,10 @@ compiler bcc: result = ( name: "bcc", objExt: "obj", - optSpeed: " -O2 -6 ", + optSpeed: " -O3 -6 ", optSize: " -O1 -6 ", - compilerExe: "bcc32", - cppCompiler: "", + compilerExe: "bcc32c", + cppCompiler: "cpp32c", compileTmpl: "-c $options $include -o$objfile $file", buildGui: " -tW", buildDll: " -tWD", @@ -193,7 +193,9 @@ compiler bcc: pic: "", asmStmtFrmt: "__asm{$n$1$n}$n", structStmtFmt: "$1 $2", - props: {hasCpp}) + props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, + hasAttribute}) + # Digital Mars C Compiler compiler dmc: diff --git a/compiler/options.nim b/compiler/options.nim index 40e97e94f..69a555b3f 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -149,6 +149,7 @@ var gExperimentalMode*: bool newDestructors*: bool gDynlibOverrideAll*: bool + useNimNamespace*: bool type SymbolFilesOption* = enum diff --git a/doc/advopt.txt b/doc/advopt.txt index 345e20fe4..214ac8dd2 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -76,6 +76,7 @@ Advanced options: --NimblePath:PATH add a path for Nimble support --noNimblePath deactivate the Nimble path --noCppExceptions use default exception handling with C++ backend + --cppCompileToNamespace use namespace "Nim" for the generated C++ code --excludePath:PATH exclude a path from the list of search paths --dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL has no effect and can be statically linked instead; diff --git a/lib/nimbase.h b/lib/nimbase.h index a03407c4f..20ac9979b 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -264,6 +264,11 @@ __clang__ # define HAVE_STDINT_H #endif +/* wrap all Nim typedefs into namespace Nim */ +#ifdef USE_NIM_NAMESPACE +namespace Nim { +#endif + /* bool types (C++ has it): */ #ifdef __cplusplus # ifndef NIM_TRUE @@ -413,8 +418,8 @@ typedef struct TStringDesc* string; # endif #endif -typedef struct TFrame TFrame; -struct TFrame { +typedef struct TFrame_ TFrame; +struct TFrame_ { TFrame* prev; NCSTRING procname; NI line; @@ -476,6 +481,10 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } "error: 'Nim_and_C_compiler_disagree_on_target_architecture' declared as an array with a negative size" */ typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1]; +#ifdef USE_NIM_NAMESPACE +} +#endif + #ifdef __cplusplus # define NIM_EXTERNC extern "C" #else diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index afc435638..fa3700190 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -295,7 +295,7 @@ else: when (defined(x86) or defined(amd64)) and defined(vcc): proc cpuRelax* {.importc: "YieldProcessor", header: "<windows.h>".} -elif (defined(x86) or defined(amd64)) and someGcc: +elif (defined(x86) or defined(amd64)) and (someGcc or defined(bcc)): proc cpuRelax* {.inline.} = {.emit: """asm volatile("pause" ::: "memory");""".} elif someGcc or defined(tcc): |