summary refs log tree commit diff stats
path: root/nim/semexprs.pas
diff options
context:
space:
mode:
Diffstat (limited to 'nim/semexprs.pas')
-rwxr-xr-xnim/semexprs.pas69
1 files changed, 32 insertions, 37 deletions
diff --git a/nim/semexprs.pas b/nim/semexprs.pas
index 2fd0d6843..43eb9ac6f 100755
--- a/nim/semexprs.pas
+++ b/nim/semexprs.pas
@@ -13,7 +13,7 @@
 function semTemplateExpr(c: PContext; n: PNode; s: PSym;
                          semCheck: bool = true): PNode;
 begin
-  include(s.flags, sfUsed);
+  markUsed(n, s);
   pushInfoContext(n.info);
   result := evalTemplate(c, n, s);
   if semCheck then
@@ -47,8 +47,6 @@ var
   diff: int;
 begin
   diff := inheritanceDiff(castDest, src);
-  //if diff = 0 then
-  //  liMessage(info, hintConvToBaseNotNeeded)
   if diff = high(int) then
     liMessage(info, errGenerated,
       format(MsgKindToString(errIllegalConvFromXtoY),
@@ -136,7 +134,7 @@ begin
   else begin
     for i := 0 to sonsLen(op)-1 do begin
       if sameType(result.typ, op.sons[i].typ) then begin
-        include(op.sons[i].sym.flags, sfUsed);
+        markUsed(n, op.sons[i].sym);
         result := op.sons[i]; exit
       end
     end;
@@ -453,8 +451,7 @@ const
   FakeVarParams = {@set}[mNew, mNewFinalize, mInc, ast.mDec, mIncl,
                          mExcl, mSetLengthStr, mSetLengthSeq,
                          mAppendStrCh, mAppendStrStr, mSwap,
-                         mAppendSeqElem, mAppendSeqSeq,
-                         mNewSeq];
+                         mAppendSeqElem, mNewSeq];
 var
   i: int;
   t: PType;
@@ -474,7 +471,7 @@ var
   callee: PSym;
 begin
   if not (efWantIterator in flags) then 
-    result := semDirectCall(c, n, {@set}[skProc, skConverter])
+    result := semDirectCall(c, n, {@set}[skProc, skMethod, skConverter])
   else
     result := semDirectCall(c, n, {@set}[skIterator]);
   if result <> nil then begin
@@ -586,17 +583,23 @@ begin
   result := n;
 end;
 
-function LookUpForDefined(c: PContext; n: PNode): PSym;
+function LookUpForDefined(c: PContext; n: PNode; onlyCurrentScope: bool): PSym;
 var
   m: PSym;
   ident: PIdent;
 begin
   case n.kind of
-    nkIdent: result := SymtabGet(c.Tab, n.ident); // no need for stub loading
+    nkIdent: begin
+      if onlyCurrentScope then
+        result := SymtabLocalGet(c.tab, n.ident)
+      else
+        result := SymtabGet(c.Tab, n.ident); // no need for stub loading
+    end;
     nkDotExpr, nkQualified: begin
-      checkSonsLen(n, 2);
       result := nil;
-      m := LookupForDefined(c, n.sons[0]);
+      if onlyCurrentScope then exit;
+      checkSonsLen(n, 2);
+      m := LookupForDefined(c, n.sons[0], onlyCurrentScope);
       if (m <> nil) and (m.kind = skModule) then begin
         if (n.sons[1].kind = nkIdent) then begin
           ident := n.sons[1].ident;
@@ -612,7 +615,7 @@ begin
     end;
     nkAccQuoted: begin
       checkSonsLen(n, 1);
-      result := lookupForDefined(c, n.sons[0]);
+      result := lookupForDefined(c, n.sons[0], onlyCurrentScope);
     end
     else begin
       liMessage(n.info, errIdentifierExpected, renderTree(n));
@@ -621,14 +624,14 @@ begin
   end
 end;
 
-function semDefined(c: PContext; n: PNode): PNode;
+function semDefined(c: PContext; n: PNode; onlyCurrentScope: bool): PNode;
 begin
   checkSonsLen(n, 2);
   result := newIntNode(nkIntLit, 0);
   // we replace this node by a 'true' or 'false' node
-  if LookUpForDefined(c, n.sons[1]) <> nil then
+  if LookUpForDefined(c, n.sons[1], onlyCurrentScope) <> nil then
     result.intVal := 1
-  else if (n.sons[1].kind = nkIdent)
+  else if not onlyCurrentScope and (n.sons[1].kind = nkIdent)
       and condsyms.isDefined(n.sons[1].ident) then
     result.intVal := 1;
   result.info := n.info;
@@ -647,8 +650,8 @@ function semMagic(c: PContext; n: PNode; s: PSym; flags: TExprFlags): PNode;
 begin
   result := n;
   case s.magic of // magics that need special treatment
-    mDefined: result := semDefined(c, setMs(n, s));
-    mDefinedInScope: result := semDefinedInScope(c, setMs(n, s));
+    mDefined: result := semDefined(c, setMs(n, s), false);
+    mDefinedInScope: result := semDefined(c, setMs(n, s), true);
     mLow:     result := semLowHigh(c, setMs(n, s), mLow);
     mHigh:    result := semLowHigh(c, setMs(n, s), mHigh);
     mSizeOf:  result := semSizeof(c, setMs(n, s));
@@ -658,11 +661,6 @@ begin
   end;
 end;
 
-procedure checkDeprecated(n: PNode; s: PSym);
-begin
-  if sfDeprecated in s.flags then liMessage(n.info, warnDeprecated, s.name.s);  
-end;
-
 function isTypeExpr(n: PNode): bool;
 begin
   case n.kind of
@@ -795,7 +793,7 @@ begin
       result := newSymNode(f);
       result.info := n.info;
       result.typ := ty;
-      checkDeprecated(n, f);
+      markUsed(n, f);
     end
     else
       liMessage(n.sons[1].info, errEnumHasNoValueX, i.s);
@@ -823,7 +821,7 @@ begin
         n.sons[0] := makeDeref(n.sons[0]);
         n.sons[1] := newSymNode(f); // we now have the correct field
         n.typ := f.typ;
-        checkDeprecated(n, f);
+        markUsed(n, f);
         if check = nil then result := n
         else begin
           check.sons[0] := n;
@@ -841,7 +839,7 @@ begin
       n.sons[1] := newSymNode(f);
       n.typ := f.typ;
       result := n;
-      checkDeprecated(n, f);
+      markUsed(n, f);
       exit
     end
   end;
@@ -851,7 +849,7 @@ begin
   //if (f <> nil) and (f.kind = skStub) then loadStub(f);
   // ``loadStub`` is not correct here as we don't care for ``f`` really
   if (f <> nil) then begin
-    // BUGFIX: do not check for (f.kind in [skProc, skIterator]) here
+    // BUGFIX: do not check for (f.kind in [skProc, skMethod, skIterator]) here
     result := newNodeI(nkDotCall, n.info);
     // This special node kind is to merge with the call handler in `semExpr`.
     addSon(result, newIdentNode(i, n.info));
@@ -1145,7 +1143,6 @@ begin
     a := n.sons[0];
   s := qualifiedLookup(c, a, false);
   if (s <> nil) then begin
-    checkDeprecated(n, s);
     case s.kind of
       skMacro: result := semMacroExpr(c, n, s, semCheck);
       skTemplate: begin
@@ -1176,7 +1173,7 @@ begin
   if (s.kind = skType) and not (efAllowType in flags) then
     liMessage(n.info, errATypeHasNoValue);
   case s.kind of
-    skProc, skIterator, skConverter: begin
+    skProc, skMethod, skIterator, skConverter: begin
       if (s.magic <> mNone) then
         liMessage(n.info, errInvalidContextForBuiltinX, s.name.s);
       result := symChoice(c, n, s);
@@ -1194,7 +1191,7 @@ begin
         copy `x`'s AST into each context, so that the type fixup phase can
         deal with two different ``[]``.
       *)
-      include(s.flags, sfUsed);
+      markUsed(n, s);
       if s.typ.kind in ConstAbstractTypes then begin
         result := copyTree(s.ast);
         result.info := n.info;
@@ -1208,7 +1205,7 @@ begin
     skMacro: result := semMacroExpr(c, n, s);
     skTemplate: result := semTemplateExpr(c, n, s);
     skVar: begin
-      include(s.flags, sfUsed);
+      markUsed(n, s);
       // if a proc accesses a global variable, it is not side effect free
       if sfGlobal in s.flags then include(c.p.owner.flags, sfSideEffect);
       result := newSymNode(s);
@@ -1219,12 +1216,11 @@ begin
       result := semExpr(c, s.ast);
     end
     else begin
-      include(s.flags, sfUsed);
+      markUsed(n, s);
       result := newSymNode(s);
       result.info := n.info;
     end
   end;
-  checkDeprecated(n, s);
 end;
 
 function semDotExpr(c: PContext; n: PNode; flags: TExprFlags): PNode;
@@ -1259,7 +1255,7 @@ begin
       if (s.kind = skType) and not (efAllowType in flags) then
         liMessage(n.info, errATypeHasNoValue);
       if (s.magic <> mNone) and
-          (s.kind in [skProc, skIterator, skConverter]) then
+          (s.kind in [skProc, skMethod, skIterator, skConverter]) then
         liMessage(n.info, errInvalidContextForBuiltinX, s.name.s); *)
       // because of the changed symbol binding, this does not mean that we
       // don't have to check the symbol for semantics here again!
@@ -1296,18 +1292,16 @@ begin
       checkMinSonsLen(n, 1);
       s := qualifiedLookup(c, n.sons[0], false);
       if (s <> nil) then begin
-        checkDeprecated(n, s);
         case s.kind of
           skMacro: result := semMacroExpr(c, n, s);
           skTemplate: result := semTemplateExpr(c, n, s);
           skType: begin
-            include(s.flags, sfUsed);
             if n.kind <> nkCall then
               liMessage(n.info, errXisNotCallable, s.name.s);
             // XXX does this check make any sense?
             result := semConv(c, n, s);
           end;
-          skProc, skConverter, skIterator: begin
+          skProc, skMethod, skConverter, skIterator: begin
             if s.magic = mNone then result := semDirectOp(c, n, flags)
             else result := semMagic(c, n, s, flags);
           end;
@@ -1328,7 +1322,8 @@ begin
     nkBracketExpr: begin
       checkMinSonsLen(n, 1);
       s := qualifiedLookup(c, n.sons[0], false);
-      if (s <> nil) and (s.kind in [skProc, skConverter, skIterator]) then begin
+      if (s <> nil)
+      and (s.kind in [skProc, skMethod, skConverter, skIterator]) then begin
         // type parameters: partial generic specialization
         // XXX: too implement!
         internalError(n.info, 'explicit generic instantation not implemented');