summary refs log tree commit diff stats
path: root/compiler/ast.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ast.nim')
-rw-r--r--compiler/ast.nim24
1 files changed, 15 insertions, 9 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 0652bd3e7..97f48b253 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -13,7 +13,7 @@ import
   msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists, 
   intsets, idgen
 
-type 
+type
   TCallingConvention* = enum 
     ccDefault,                # proc has no explicit calling convention
     ccStdCall,                # procedure is stdcall
@@ -299,7 +299,7 @@ const
   nkEffectList* = nkArgList 
   # hacks ahead: an nkEffectList is a node with 4 children:
   exceptionEffects* = 0 # exceptions at position 0
-  readEffects* = 1      # read effects at position 1
+  usesEffects* = 1      # read effects at position 1
   writeEffects* = 2     # write effects at position 2
   tagEffects* = 3       # user defined tag ('gc', 'time' etc.)
   effectListLen* = 4    # list of effects list
@@ -432,7 +432,7 @@ type
     tfAcyclic,        # type is acyclic (for GC optimization)
     tfEnumHasHoles,   # enum cannot be mapped into a range
     tfShallow,        # type can be shallow copied on assignment
-    tfThread,         # proc type is marked as ``thread``
+    tfThread,         # proc type is marked as ``thread``; alias for ``gcsafe``
     tfFromGeneric,    # type is an instantiation of a generic; this is needed
                       # because for instantiations of objects, structural
                       # type equality has to be used
@@ -509,6 +509,7 @@ const
   tfIncompleteStruct* = tfVarargs
   tfUncheckedArray* = tfVarargs
   tfUnion* = tfNoSideEffect
+  tfGcSafe* = tfThread
   skError* = skUnknown
   
   # type flags that are essential for type equality:
@@ -559,7 +560,7 @@ type
     mFloat, mFloat32, mFloat64, mFloat128,
     mBool, mChar, mString, mCstring,
     mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc,
-    mVoidType, mPNimrodNode,
+    mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn,
     mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor,
     mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType,
     mNaN, mInf, mNegInf,
@@ -978,6 +979,8 @@ template `{}=`*(n: PNode, i: int, s: PNode): stmt =
 var emptyNode* = newNode(nkEmpty)
 # There is a single empty node that is shared! Do not overwrite it!
 
+var anyGlobal* = newSym(skVar, getIdent("*"), nil, unknownLineInfo())
+
 proc isMetaType*(t: PType): bool =
   return t.kind in tyMetaTypes or
          (t.kind == tyStatic and t.n == nil) or
@@ -1308,10 +1311,13 @@ proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
   result = t
   while result.kind in kinds: result = lastSon(result)
 
+proc isGCedMem*(t: PType): bool {.inline.} =
+  result = t.kind in {tyString, tyRef, tySequence} or
+           t.kind == tyProc and t.callConv == ccClosure
+
 proc propagateToOwner*(owner, elem: PType) =
   const HaveTheirOwnEmpty = {tySequence, tySet}
-  owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta,
-                                             tfHasGCedMem})
+  owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta})
   if tfNotNil in elem.flags:
     if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}:
       owner.flags.incl tfNotNil
@@ -1328,9 +1334,9 @@ proc propagateToOwner*(owner, elem: PType) =
   if elem.isMetaType:
     owner.flags.incl tfHasMeta
 
-  if elem.kind in {tyString, tyRef, tySequence} or
-      elem.kind == tyProc and elem.callConv == ccClosure:
-    owner.flags.incl tfHasGCedMem
+  if owner.kind != tyProc:
+    if elem.isGCedMem or tfHasGCedMem in elem.flags:
+      owner.flags.incl tfHasGCedMem
 
 proc rawAddSon*(father, son: PType) =
   if isNil(father.sons): father.sons = @[]