summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ast.nim6
-rwxr-xr-xcompiler/ccgtypes.nim2
-rwxr-xr-xcompiler/pragmas.nim34
-rwxr-xr-xdoc/manual.txt21
-rwxr-xr-xtodo.txt1
-rwxr-xr-xweb/news.txt2
6 files changed, 49 insertions, 17 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 0878d0b3a..cf1737c32 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -328,7 +328,7 @@ type
     nfSem       # node has been checked for semantics
 
   TNodeFlags* = set[TNodeFlag]
-  TTypeFlag* = enum 
+  TTypeFlag* = enum   # keep below 15 for efficiency reasons (now: 13)
     tfVarargs,        # procedure has C styled varargs
     tfNoSideEffect,   # procedure type does not allow side effects
     tfFinal,          # is the object final?
@@ -341,7 +341,9 @@ type
                       # type equality has to be used
     tfAll,            # type class requires all constraints to be met (default)
     tfAny,            # type class requires any constraint to be met
-    tfCapturesEnv     # whether proc really captures some environment
+    tfCapturesEnv,    # whether proc really captures some environment
+    tfByCopy,         # pass object/tuple by copy (C backend)
+    tfByRef           # pass object/tuple by reference (C backend)
 
   TTypeFlags* = set[TTypeFlag]
 
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 6f7e49e4f..c2dfb5d63 100755
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -249,6 +249,8 @@ proc getGlobalTempName(): PRope =
 proc ccgIntroducedPtr(s: PSym): bool = 
   var pt = skipTypes(s.typ, abstractInst)
   assert skResult != s.kind
+  if tfByRef in pt.flags: return true
+  elif tfByCopy in pt.flags: return false
   case pt.Kind
   of tyObject:
     if (optByRef in s.options) or (getSize(pt) > platform.floatSize * 2): 
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 273bf98e8..107660762 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -46,7 +46,7 @@ const
     wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame}
   typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, 
     wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow, 
-    wImportcpp, wImportobjc, wError, wIncompleteStruct}
+    wImportcpp, wImportobjc, wError, wIncompleteStruct, wByCopy, wByRef}
   fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, 
     wImportcpp, wImportobjc, wError}
   varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, 
@@ -483,8 +483,8 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
             processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
           of wExtern: setExternName(sym, expectStrLit(c, it))
           of wImmediate:
-            if sym.kind notin {skTemplate, skMacro}: invalidPragma(it)
-            incl(sym.flags, sfImmediate)
+            if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate)
+            else: invalidPragma(it)
           of wImportCpp:
             processImportCpp(sym, getOptionalStr(c, it, sym.name.s))
           of wImportObjC:
@@ -571,22 +571,22 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
           of wVarargs: 
             noVal(it)
             if sym.typ == nil: invalidPragma(it)
-            incl(sym.typ.flags, tfVarargs)
+            else: incl(sym.typ.flags, tfVarargs)
           of wBorrow: 
             noVal(it)
             incl(sym.flags, sfBorrow)
           of wFinal: 
             noVal(it)
             if sym.typ == nil: invalidPragma(it)
-            incl(sym.typ.flags, tfFinal)
+            else: incl(sym.typ.flags, tfFinal)
           of wAcyclic: 
             noVal(it)
             if sym.typ == nil: invalidPragma(it)
-            incl(sym.typ.flags, tfAcyclic)
+            else: incl(sym.typ.flags, tfAcyclic)
           of wShallow:
             noVal(it)
             if sym.typ == nil: invalidPragma(it)
-            incl(sym.typ.flags, tfShallow)
+            else: incl(sym.typ.flags, tfShallow)
           of wThread:
             noVal(it)
             incl(sym.flags, sfThread)
@@ -627,29 +627,37 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
           of wNoInit:
             noVal(it)
             if sym != nil: incl(sym.flags, sfNoInit)
-          of wByCopy:
-            noVal(it)
-            if sym != nil: incl(sym.flags, sfByCopy)
           of wHoist:
             noVal(it)
             if sym != nil: incl(sym.flags, sfHoist)
           of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, 
              wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, 
-             wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef,
+             wLinedir, wStacktrace, wLinetrace, wOptimization,
              wCallConv, 
              wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks: 
             processOption(c, it) # calling conventions (boring...):
           of firstCallConv..lastCallConv: 
             assert(sym != nil)
             if sym.typ == nil: invalidPragma(it)
-            sym.typ.callConv = wordToCallConv(k)
+            else: sym.typ.callConv = wordToCallConv(k)
           of wEmit: PragmaEmit(c, it)
           of wUnroll: PragmaUnroll(c, it)
           of wLinearScanEnd: PragmaLinearScanEnd(c, it)
           of wIncompleteStruct:
             noVal(it)
             if sym.typ == nil: invalidPragma(it)
-            incl(sym.typ.flags, tfIncompleteStruct)
+            else: incl(sym.typ.flags, tfIncompleteStruct)
+          of wByRef:
+            noVal(it)
+            if sym == nil or sym.typ == nil:
+              processOption(c, it)
+            else:
+              incl(sym.typ.flags, tfByRef)
+          of wByCopy:
+            noVal(it)
+            if sym.kind != skType: incl(sym.flags, sfByCopy)
+            elif sym.typ == nil: invalidPragma(it)
+            else: incl(sym.typ.flags, tfByCopy)
           of wLine: PragmaLine(c, it)
           else: invalidPragma(it)
         else: invalidPragma(it)
diff --git a/doc/manual.txt b/doc/manual.txt
index ed80984d7..5933691b0 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -2836,7 +2836,7 @@ Ordinary vs immediate templates
 
 There are two different kinds of templates: `immediate`:idx: templates and
 ordinary templates. Ordinary templates take part in overloading resolution. As
-such their arguments needs to be type checked before the template is invoked.
+such their arguments need to be type checked before the template is invoked.
 So ordinary templates cannot receive undeclared identifiers:
 
 .. code-block:: nimrod
@@ -3657,6 +3657,25 @@ identifier *exactly as spelled*:
 

 Note that this pragma is somewhat of a misnomer: Other backends will provide

 the same feature under the same name.

+
+
+Bycopy pragma
+-------------
+
+The `bycopy`:idx: pragma can be applied to an object or tuple type and
+instructs the compiler to pass the type by value to procs:
+
+.. code-block:: nimrod
+  type
+    TVector {.bycopy, pure.} = object
+      x, y, z: float
+
+
+Byref pragma
+------------
+
+The `byref`:idx: pragma can be applied to an object or tuple type and instructs
+the compiler to pass the type by reference (hidden pointer) to procs.
 

 

 Varargs pragma

diff --git a/todo.txt b/todo.txt
index 0a88dcd83..fadd7fb9e 100755
--- a/todo.txt
+++ b/todo.txt
@@ -7,7 +7,6 @@ version 0.9.0
 
 - implicit deref for parameter matching
 - ``final`` should be the default for objects
-- ``bycopy`` pragma for imported C types
 - optimize genericAssign in the code generator
 - the lookup rules for generics really are too permissive
 - fix remaining closure bugs:
diff --git a/web/news.txt b/web/news.txt
index 91c47a3d1..e9e00a321 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -124,6 +124,8 @@ Compiler Additions
   of the compiler and can thus generate documentation for symbols hiding in
   macros.
 - The compiler now supports the ``dynlib`` pragma for variables.
+- The compiler now supports ``bycopy`` and ``byref`` pragmas that affect how
+  objects/tuples are passed.
 
 
 Language Additions