summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md4
-rw-r--r--compiler/cgen.nim15
-rw-r--r--compiler/commands.nim5
-rw-r--r--compiler/extccomp.nim10
-rw-r--r--compiler/options.nim1
-rw-r--r--doc/advopt.txt1
-rw-r--r--lib/nimbase.h13
-rw-r--r--lib/system/atomics.nim2
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):