Example #1
0
  protected SemanticContext _getPredicates(NFAState s, NFAState altStartState) {
    // System.out.println("_getPredicates("+s+")");
    if (s.isAcceptState()) {
      return null;
    }

    // avoid infinite loops from (..)* etc...
    if (lookBusy.contains(s)) {
      return null;
    }
    lookBusy.add(s);

    Transition transition0 = s.transition[0];
    // no transitions
    if (transition0 == null) {
      return null;
    }

    // not a predicate and not even an epsilon
    if (!(transition0.label.isSemanticPredicate() || transition0.label.isEpsilon())) {
      return null;
    }

    SemanticContext p = null;
    SemanticContext p0 = null;
    SemanticContext p1 = null;
    if (transition0.label.isSemanticPredicate()) {
      // System.out.println("pred "+transition0.label);
      p = transition0.label.getSemanticContext();
      // ignore backtracking preds not on left edge for this decision
      if (((SemanticContext.Predicate) p).predicateAST.getType() == ANTLRParser.BACKTRACK_SEMPRED
          && s == altStartState.transition[0].target) {
        p = null; // don't count
      }
    }

    // get preds from beyond this state
    p0 = _getPredicates((NFAState) transition0.target, altStartState);

    // get preds from other transition
    Transition transition1 = s.transition[1];
    if (transition1 != null) {
      p1 = _getPredicates((NFAState) transition1.target, altStartState);
    }

    // join this&following-right|following-down
    return SemanticContext.and(p, SemanticContext.or(p0, p1));
  }
 @Override
 public Statement syntaxCopy(SemanticContext context) {
   CaseStatement s =
       context.newCaseStatement(
           filename, lineNumber, exp.syntaxCopy(context), statement.syntaxCopy(context));
   s.copySourceRange(this);
   return s;
 }
 @Override
 public boolean canThrow(SemanticContext context) {
   if (context.isD2()) {
     VarDeclaration v = declaration.isVarDeclaration();
     if (v != null && v.init != null) {
       ExpInitializer ie = v.init.isExpInitializer();
       return ie != null && ie.exp.canThrow(context);
     }
     return false;
   } else {
     return super.canThrow(context);
   }
 }
  @Override
  public Expression interpret(InterState istate, SemanticContext context) {
    Expression e = EXP_CANT_INTERPRET;
    VarDeclaration v = declaration.isVarDeclaration();
    if (v != null) {
      Dsymbol s = v.toAlias(context);
      if (s == v && !v.isStatic() && v.init() != null) {
        ExpInitializer ie = v.init().isExpInitializer();
        if (ie != null) {
          e = ie.exp.interpret(istate, context);
        } else if (v.init().isVoidInitializer() != null) {
          e = null;
        }
      } else {
        boolean condition;
        if (context.isD2()) {
          condition = s == v && (v.isConst() || v.isInvariant(context)) && v.init != null;
        } else {
          condition = s == v && v.isConst() && v.init() != null;
        }

        if (condition) {
          e = v.init().toExpression(context);
          if (null == e) {
            e = EXP_CANT_INTERPRET;
          } else if (null == e.type) {
            e.type = v.type;
          }
        } else if (declaration.isAttribDeclaration() != null
            || declaration.isTemplateMixin() != null
            || declaration.isTupleDeclaration()
                != null) { // These can be made to work, too lazy now
          e = EXP_CANT_INTERPRET;
        } else { // Others should not contain executable code, so are trivial to evaluate
          e = null;
        }
      }
    }
    return e;
  }
  @Override
  public Expression semantic(Scope sc, SemanticContext context) {
    if (type != null) {
      return this;
    }

    /* This is here to support extern(linkage) declaration,
     * where the extern(linkage) winds up being an AttribDeclaration
     * wrapper.
     */
    Dsymbol s = declaration;

    AttribDeclaration ad = declaration.isAttribDeclaration();
    if (ad != null) {
      if (ad.decl != null && ad.decl.size() == 1) {
        s = ad.decl.get(0);
      }
    }

    if (s.isVarDeclaration() != null) { // Do semantic() on initializer first, so:
      //	int a = a;
      // will be illegal.
      declaration.semantic(sc, context);
      s.parent = sc.parent;
    }

    // Insert into both local scope and function scope.
    // Must be unique in both.
    if (s.ident != null) {
      if (sc.insert(s) == null) {
        if (context.acceptsErrors()) {
          context.acceptProblem(
              Problem.newSemanticTypeErrorLoc(
                  IProblem.DeclarationIsAlreadyDefined, s, s.toChars(context)));
        }
      } else if (sc.func != null) {
        // VarDeclaration v = s.isVarDeclaration();
        if ((s.isFuncDeclaration() != null /*|| v && v.storage_class & STCstatic*/)
            && sc.func.localsymtab.insert(s) == null) {
          if (context.acceptsErrors()) {
            context.acceptProblem(
                Problem.newSemanticTypeError(
                    IProblem.DeclarationIsAlreadyDefinedInAnotherScope,
                    this,
                    s.toPrettyChars(context),
                    sc.func.toChars(context)));
          }
        } else if (!context.global.params.useDeprecated) { // Disallow shadowing

          for (Scope scx = sc.enclosing; scx != null && scx.func == sc.func; scx = scx.enclosing) {
            Dsymbol s2;

            if (scx.scopesym != null
                && scx.scopesym.symtab != null
                && (s2 = scx.scopesym.symtab.lookup(s.ident)) != null
                && s != s2) {
              if (context.acceptsErrors()) {
                context.acceptProblem(
                    Problem.newSemanticTypeErrorLoc(
                        IProblem.ShadowingDeclarationIsDeprecated, s, s.toPrettyChars(context)));
              }
            }
          }
        }
      }
    }
    if (s.isVarDeclaration() == null) {
      declaration.semantic(sc, context);
      s.parent = sc.parent;
    }
    // Commented this for Descent: we want semantic even if there are errors
    //		if (context.global.errors == 0) {
    declaration.semantic2(sc, context);
    //			if (context.global.errors == 0) {
    declaration.semantic3(sc, context);
    //			}
    //		}

    type = Type.tvoid;
    return this;
  }
  @Override
  public Statement semantic(Scope sc, SemanticContext context) {
    SwitchStatement sw = sc.sw;
    this.sw = sw;

    exp = exp.semantic(sc, context);
    if (sw != null) {
      int i;

      exp = exp.implicitCastTo(sc, sw.condition.type, context);
      exp = exp.optimize(WANTvalue | WANTinterpret, context);

      boolean gotoL1 = false;

      if (context.isD2()) {
        /* This is where variables are allowed as case expressions.
         */
        if (exp.op == TOKvar) {
          VarExp ve = (VarExp) exp;
          VarDeclaration v = ve.var.isVarDeclaration();
          Type t = exp.type.toBasetype(context);
          if (v != null && (t.isintegral() || t.ty == Tclass)) {
              /* Flag that we need to do special code generation
               * for this, i.e. generate a sequence of if-then-else
               */
            sw.hasVars = 1;
            // goto L1;
            gotoL1 = true;
          }
        }
      }

      if (!gotoL1) {
        if (exp.op != TOKstring && exp.op != TOKint64) {
          if (context.acceptsErrors()) {
            context.acceptProblem(
                Problem.newSemanticTypeError(
                    IProblem.CaseMustBeAnIntegralOrStringConstant,
                    sourceExp,
                    exp.toChars(context)));
          }
          exp = new IntegerExp(0);
        }
      }

      // L1:
      for (i = 0; i < sw.cases.size(); i++) {
        CaseStatement cs = (CaseStatement) sw.cases.get(i);

        if (cs.exp.equals(exp, context)) {
          if (context.acceptsErrors()) {
            context.acceptProblem(
                Problem.newSemanticTypeErrorLoc(
                    IProblem.DuplicateCaseInSwitchStatement, this, exp.toChars(context)));
          }
          break;
        }
      }

      sw.cases.add(this);

      // Resolve any goto case's with no exp to this case statement
      if (sw.gotoCases != null) {
        for (i = 0; i < sw.gotoCases.size(); i++) {
          GotoCaseStatement gcs = (GotoCaseStatement) sw.gotoCases.get(i);

          if (gcs.exp == null) {
            gcs.cs = this;
            sw.gotoCases.remove(i); // remove from array
          }
        }
      }

      if (context.isD2()) {
        if (sc.sw.tf != sc.tf) {
          if (context.acceptsErrors()) {
            context.acceptProblem(
                Problem.newSemanticTypeErrorLoc(
                    IProblem.SwitchAndCaseAreInDifferentFinallyBlocks, this));
          }
        }
      }
    } else {
      if (context.acceptsErrors()) {
        context.acceptProblem(Problem.newSemanticTypeError(IProblem.CaseIsNotInSwitch, this));
      }
    }
    statement = statement.semantic(sc, context);
    return this;
  }