예제 #1
0
static void
view_ast(BaseAST* ast, bool number = false, int mark = -1, int indent = 0) {
  if (!ast)
    return;
  if (Expr* expr = toExpr(ast)) {
    printf("\n");
    for (int i = 0; i < indent; i++)
      printf(" ");
    printf("(");
    if (ast->id == mark)
      printf("***");
    if (number)
      printf("%d ", ast->id);
    printf("%s", expr->astTagAsString());

    if (isBlockStmt(expr))
      if (FnSymbol* fn = toFnSymbol(expr->parentSymbol))
        if (expr == fn->where)
          printf(" where");

    if (GotoStmt *gs= toGotoStmt(ast)) {
      printf( " ");
      view_ast(gs->label, number, mark, indent+1);
    }

    if (CallExpr* call = toCallExpr(expr))
      if (call->primitive)
        printf(" %s", call->primitive->name);

    if (NamedExpr* named = toNamedExpr(expr))
      printf(" \"%s\"", named->name);

    if (toDefExpr(expr))
      printf(" ");

    int64_t i;
    const char *str;
    if (get_int(expr, &i)) {
      printf(" %" PRId64, i);
    } else if (get_string(expr, &str)) {
      printf(" \"%s\"", str);
    }

    if (SymExpr* sym = toSymExpr(expr)) {
      printf(" ");
      view_sym(sym->var, number, mark);
    } else if (UnresolvedSymExpr* sym = toUnresolvedSymExpr(expr)) {
      printf(" '%s'", sym->unresolved);
    }
  }

  if (Symbol* sym = toSymbol(ast)) {
    view_sym(sym, number, mark);
  }

  AST_CHILDREN_CALL(ast, view_ast, number, mark, indent+2);

  if (toExpr(ast))
    printf(")");
}
예제 #2
0
파일: stmt.cpp 프로젝트: chapel-lang/chapel
BlockStmt*
BlockStmt::copyInner(SymbolMap* map) {
  BlockStmt* _this = new BlockStmt();

  _this->blockTag  = blockTag;
  _this->blockInfo = COPY_INT(blockInfo);
  _this->useList   = COPY_INT(useList);
  _this->byrefVars = COPY_INT(byrefVars);

  for_alist(expr, body) {
    Expr* copy = COPY_INT(expr);
    _this->insertAtTail(copy);

    if (DefExpr* def = toDefExpr(copy)) {
      if (TypeSymbol* ts = toTypeSymbol(def->sym)) {
        if (EnumType* et = toEnumType(ts->type)) {
          // ensure we have the size, cast functions, etc.
          // Lydia NOTE: This relies on making no copies of enum types prior to
          // buildDefaultFunctions().  The creation must happen here because
          // otherwise the EnumType will not have the correct symbol, and the
          // symbol will not be in the tree.

          buildEnumFunctions(et);
        }
      }
    }
  }
예제 #3
0
  forv_Vec(DefExpr, def, gDefExprs) {
    if (toVarSymbol(def->sym)) {
      // The test for FLAG_TEMP allows compiler-generated (temporary) variables
      // to be declared without an explicit type or initializer expression.
      if ((!def->init || def->init->isNoInitExpr())
          && !def->exprType && !def->sym->hasFlag(FLAG_TEMP))
        if (isBlockStmt(def->parentExpr) && !isArgSymbol(def->parentSymbol))
          if (def->parentExpr != rootModule->block && def->parentExpr != stringLiteralModule->block)
            if (!def->sym->hasFlag(FLAG_INDEX_VAR))
              USR_FATAL_CONT(def->sym,
                             "Variable '%s' is not initialized or has no type",
                             def->sym->name);
    }

    //
    // This test checks to see if query domains (e.g., '[?D]') are
    // used in places other than formal argument type specifiers.
    //
    if (!isFnSymbol(def->parentSymbol)) {
      if (CallExpr* type = toCallExpr(def->exprType)) {
        if (type->isNamed("chpl__buildArrayRuntimeType")) {
          if (CallExpr* domainExpr = toCallExpr(type->get(1))) {
            DefExpr* queryDomain = toDefExpr(domainExpr->get(1));
            if (queryDomain) {
              USR_FATAL_CONT(queryDomain,
                             "Domain query expressions may currently only be used in formal argument types");
            }
          }
        }
      }
    }

    checkPrivateDecls(def);
  }
예제 #4
0
//
// Determine the index type for a ParamForLoop.
//
// This implementation creates a range with low/high values and then
// asks for its type.
//
Type* ParamForLoop::indexType()
{
  SymExpr*  lse     = lowExprGet();
  SymExpr*  hse     = highExprGet();
  CallExpr* range    = new CallExpr("chpl_build_bounded_range",
                                    lse->copy(), hse->copy());
  Type*     idxType = 0;

  insertBefore(range);

  resolveCall(range);

  if (FnSymbol* sym = range->isResolved())
  {
    resolveFormals(sym);

    DefExpr* formal = toDefExpr(sym->formals.get(1));

    if (toArgSymbol(formal->sym)->typeExpr)
      idxType = toArgSymbol(formal->sym)->typeExpr->body.tail->typeInfo();
    else
      idxType = formal->sym->type;

    range->remove();
  }
  else
  {
    INT_FATAL("unresolved range");
  }

  return idxType;
}
예제 #5
0
파일: stmt.cpp 프로젝트: deniskin82/chapel
GenRet BlockStmt::codegen() {
  GenInfo* info = gGenInfo;
  FILE* outfile = info->cfile;
  GenRet ret;

  codegenStmt(this);

  if( outfile ) {
    if (blockInfo) {
      if (blockInfo->isPrimitive(PRIM_BLOCK_WHILEDO_LOOP)) {
        std::string hdr = "while (" + codegenValue(blockInfo->get(1)).c + ") ";
        info->cStatements.push_back(hdr);
      } else if (blockInfo->isPrimitive(PRIM_BLOCK_DOWHILE_LOOP)) {
        info->cStatements.push_back("do ");
      } else if (blockInfo->isPrimitive(PRIM_BLOCK_FOR_LOOP)) {
        std::string hdr = "for (;" + codegenValue(blockInfo->get(1)).c + ";) ";
        info->cStatements.push_back(hdr);
      } else if (blockInfo->isPrimitive(PRIM_BLOCK_XMT_PRAGMA_FORALL_I_IN_N)) {
        std::string hdr = "_Pragma(\"mta for all streams ";
        hdr += codegenValue(blockInfo->get(1)).c;
        hdr += " of ";
        hdr += codegenValue(blockInfo->get(2)).c;
        hdr += "\")\n";
        info->cStatements.push_back(hdr);
      }
    }

    if (this != getFunction()->body)
      info->cStatements.push_back("{\n");

    if (!(fNoRepositionDefExpr)) {
      Vec<BaseAST*> asts;
      collect_top_asts(this, asts);
      forv_Vec(BaseAST, ast, asts) {
        if (DefExpr* def = toDefExpr(ast)) {
          if (def->parentExpr == this) {
            if (!toTypeSymbol(def->sym)) {
              if (fGenIDS && isVarSymbol(def->sym))
                info->cStatements.push_back("/* " + numToString(def->sym->id) + " */ ");
              def->sym->codegenDef();
            }
          }
        }
      }
    }

    body.codegen("");

    if (blockInfo && blockInfo->isPrimitive(PRIM_BLOCK_DOWHILE_LOOP)) {
      std::string ftr = "} while (" + codegenValue(blockInfo->get(1)).c + ");\n";
      info->cStatements.push_back(ftr);
    } else if (this != getFunction()->body) {
      std::string end = "}";
      CondStmt* cond = toCondStmt(parentExpr);
      if (!cond || !(cond->thenStmt == this && cond->elseStmt))
        end += "\n";
      info->cStatements.push_back(end);
    }
  } else {
예제 #6
0
void IpeModuleRoot::init()
{
  mState = kResolved;

  initialize();

  for (int i = 1; i <= sHighWater; i++)
  {
    DefExpr* expr = toDefExpr(rootModule->block->body.get(i));

    INT_ASSERT(expr);

    if      (mEnv->findLocal(expr->sym->name) != NULL)
    {
      printf("   Attempt to redefine identifier %s\n", expr->sym->name);
      INT_ASSERT(false);
    }

    else if (TypeSymbol* sym = toTypeSymbol(expr->sym))
    {
      int        offset = mEnv->allocateValue(sym->type);
      VarSymbol* var    = new VarSymbol(sym->name, gIpeTypeType);

      INT_ASSERT(expr->exprType == NULL);
      INT_ASSERT(expr->init     == NULL);

      var->addFlag(FLAG_CONST);
      var->locationSet(0, offset);

      mEnv->varAdd(var);
    }

    else if (expr->sym->isImmediate() == true)
    {
      VarSymbol* var    = toVarSymbol(expr->sym);
      int        offset = mEnv->allocateValue(var->type);

      var->addFlag(FLAG_CONST);
      var->locationSet(0, offset);

      mEnv->varAdd(var);
    }

    else
    {
      AstDumpToNode logger(stdout, 3);

      printf("Unexpected expression while initializing RootModule\n");
      printf("   ");
      expr->accept(&logger);
      printf("\n");

      INT_ASSERT(false);
    }
  }

  moduleAdd(this);
}
예제 #7
0
파일: expr.cpp 프로젝트: bollu/chapel
bool Expr::isModuleDefinition() {
  bool retval = false;

#if 1
  //  MDN 2014/07/02
  //  Leaving the old definition here until the scope-less BlockStmt
  //  change is stable.
  if (BlockStmt* block = toBlockStmt(this))
    if (block->length() == 1)
      if (DefExpr* def = toDefExpr(block->body.only()))
        if (isModuleSymbol(def->sym))
          retval = true;
#endif

  if (DefExpr* def = toDefExpr(this))
    if (isModuleSymbol(def->sym))
      retval = true;

  return retval;
}
//
// Removes gotos where the label immediately follows the goto and
// unused labels
//
void removeUnnecessaryGotos(FnSymbol* fn) {
  std::vector<BaseAST*> asts;
  std::set<BaseAST*> labels;
  collect_asts_STL(fn, asts);
  for_vector(BaseAST, ast, asts) {
    if (GotoStmt* gotoStmt = toGotoStmt(ast)) {
      DefExpr* def = toDefExpr(gotoStmt->next);
      SymExpr* label = toSymExpr(gotoStmt->label);
      INT_ASSERT(label);
      if (def && def->sym == label->var)
        gotoStmt->remove();
      else
        labels.insert(label->var);
    }
  }

  for_vector(BaseAST, ast2, asts) {
    if (DefExpr* def = toDefExpr(ast2))
      if (LabelSymbol* label = toLabelSymbol(def->sym))
        if (labels.find(label) == labels.end())
          def->remove();
  }
}
예제 #9
0
파일: expr.cpp 프로젝트: bollu/chapel
void Expr::replace(Expr* new_ast) {
  if (new_ast->parentSymbol || new_ast->parentExpr)
    INT_FATAL(new_ast, "Argument is already in AST in Expr::replace");
  if (new_ast->list)
    INT_FATAL(new_ast, "Argument is in a list in Expr::replace");
  if (list) {
    new_ast->next = next;
    new_ast->prev = prev;
    new_ast->list = list;
    if (next)
      next->prev = new_ast;
    else
      list->tail = new_ast;
    if (prev)
      prev->next = new_ast;
    else
      list->head = new_ast;
    next = NULL;
    prev = NULL;
    list = NULL;
  } else {
    callReplaceChild(this, new_ast);
  }

  Symbol* myParentSymbol = parentSymbol;
  Expr* myParentExpr = parentExpr;
  remove_help(this, 'p');
  insert_help(new_ast, myParentExpr, myParentSymbol);

  // Update the _this field in a FnSymbol if necessary.
  if (DefExpr* def = toDefExpr(this))
    if (ArgSymbol* arg = toArgSymbol(def->sym))
      if (FnSymbol* fn = toFnSymbol(myParentSymbol))
        if (fn->_this == arg)
          fn->_this = toDefExpr(new_ast)->sym;
}
예제 #10
0
파일: FnSymbol.cpp 프로젝트: DawidvC/chapel
void FnSymbol::verify() {
  Symbol::verify();

  if (astTag != E_FnSymbol) {
    INT_FATAL(this, "Bad FnSymbol::astTag");
  }

  if (_this && _this->defPoint->parentSymbol != this)
    INT_FATAL(this, "Each method must contain a 'this' declaration.");

  if (normalized) {
    CallExpr* last = toCallExpr(body->body.last());

    if (last == NULL || last->isPrimitive(PRIM_RETURN) == false) {
      INT_FATAL(this, "Last statement in normalized function is not a return");
    }
  }

  if (formals.parent != this) {
    INT_FATAL(this, "Bad AList::parent in FnSymbol");
  }

  if (where && where->parentSymbol != this) {
    INT_FATAL(this, "Bad FnSymbol::where::parentSymbol");
  }

  if (retExprType && retExprType->parentSymbol != this) {
    INT_FATAL(this, "Bad FnSymbol::retExprType::parentSymbol");
  }

  if (body && body->parentSymbol != this) {
    INT_FATAL(this, "Bad FnSymbol::body::parentSymbol");
  }

  for_alist(fExpr, formals) {
    DefExpr* argDef = toDefExpr(fExpr);

    INT_ASSERT(argDef);
    INT_ASSERT(isArgSymbol(argDef->sym));
  }
예제 #11
0
파일: stmt.cpp 프로젝트: jcazzie/chapel
GenRet GotoStmt::codegen() {
  GenInfo* info = gGenInfo;
  FILE* outfile = info->cfile;
  GenRet ret;

  codegenStmt(this);
  if( outfile ) {
    info->cStatements.push_back("goto " + label->codegen().c + ";\n");
  } else {
#ifdef HAVE_LLVM
    llvm::Function *func = info->builder->GetInsertBlock()->getParent();

    const char *cname;
    if(isDefExpr(label)) {
      cname = toDefExpr(label)->sym->cname;
    }
    else {
      cname = toSymExpr(label)->symbol()->cname;
    }

    llvm::BasicBlock *blockLabel;
    if(!(blockLabel = info->lvt->getBlock(cname))) {
      blockLabel = llvm::BasicBlock::Create(info->module->getContext(), cname);
      info->lvt->addBlock(cname, blockLabel);
    }

    info->builder->CreateBr(blockLabel);

    getFunction()->codegenUniqueNum++;

    llvm::BasicBlock *afterGoto = llvm::BasicBlock::Create(
        info->module->getContext(), FNAME("afterGoto"));
    func->getBasicBlockList().push_back(afterGoto);
    info->builder->SetInsertPoint(afterGoto);

#endif
  }
  return ret;
}
예제 #12
0
static void
list_ast(BaseAST* ast, BaseAST* parentAst = NULL, int indent = 0) {
  bool do_list_line = false;
  bool is_C_loop = false;
  const char* block_explain = NULL;
  if (Expr* expr = toExpr(ast)) {
    do_list_line = !parentAst || list_line(expr, parentAst);
    if (do_list_line) {
      printf("%-7d ", expr->id);
      for (int i = 0; i < indent; i++)
        printf(" ");
    }
    if (GotoStmt* e = toGotoStmt(ast)) {
      printf("goto ");
      if (SymExpr* label = toSymExpr(e->label)) {
        if (label->var != gNil) {
          list_ast(e->label, ast, indent+1);
        }
      } else {
        list_ast(e->label, ast, indent+1);
      }
    } else if (toBlockStmt(ast)) {
      block_explain = block_explanation(ast, parentAst);
      printf("%s{\n", block_explain);
    } else if (toCondStmt(ast)) {
      printf("if ");
    } else if (CallExpr* e = toCallExpr(expr)) {
      if (e->isPrimitive(PRIM_BLOCK_C_FOR_LOOP))
          is_C_loop = true;
      if (e->primitive)
        printf("%s( ", e->primitive->name);
      else
        printf("call( ");
    } else if (NamedExpr* e = toNamedExpr(expr)) {
      printf("%s = ", e->name);
    } else if (toDefExpr(expr)) {
      printf("def ");
    } else if (SymExpr* e = toSymExpr(expr)) {
      list_sym(e->var, false);
    } else if (UnresolvedSymExpr* e = toUnresolvedSymExpr(expr)) {
      printf("%s ", e->unresolved);
    }
  }

  if (Symbol* sym = toSymbol(ast))
    list_sym(sym);

  bool early_newline = toFnSymbol(ast) || toModuleSymbol(ast); 
  if (early_newline || is_C_loop)
    printf("\n");

  int new_indent = indent;

  if (isExpr(ast))
    if (do_list_line)
      new_indent = indent+2;

  AST_CHILDREN_CALL(ast, list_ast, ast, new_indent);

  if (Expr* expr = toExpr(ast)) {
    CallExpr* parent_C_loop = NULL;
    if (CallExpr* call = toCallExpr(parentAst))
      if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP))
        parent_C_loop = call;
    if (toCallExpr(expr)) {
      printf(") ");
    }
    if (toBlockStmt(ast)) {
      printf("%-7d ", expr->id);
      if (*block_explain)
        indent -= 2;
      for (int i = 0; i < indent; i++)
        printf(" ");
      if ((parent_C_loop && parent_C_loop->get(3) == expr) || *block_explain)
        printf("} ");
      else
        printf("}\n");
    } else if (CondStmt* cond = toCondStmt(parentAst)) {
      if (cond->condExpr == expr)
        printf("\n");
    } else if (!toCondStmt(expr) && do_list_line) {
      DefExpr* def = toDefExpr(expr);
      if (!(def && early_newline))
        if (!parent_C_loop)
          printf("\n");
    }
  }
}
예제 #13
0
// Returns max local frame space to evaluate this expr
int locationExpr(Expr* expr, IpeEnv* env)
{
  int retval = 0;

  if (DefExpr* defExpr = toDefExpr(expr))
  {
    VarSymbol* var   = toVarSymbol(defExpr->sym);
    int        delta = 8;           // NOAKES  Size of every type is currently 8

    INT_ASSERT(var);

    env->locationSet(var);

    retval = delta;
  }

  else if (isCallExpr(expr) == true)
    retval = 0;

  else if (CondStmt*    stmt = toCondStmt(expr))
  {
    if (stmt->elseStmt == NULL)
    {
      retval = locationExpr(stmt->thenStmt, env);
    }

    else
    {
      int thenSize = locationExpr(stmt->thenStmt, env);
      int elseSize = locationExpr(stmt->elseStmt, env);

      retval = (thenSize > elseSize) ? thenSize : elseSize;
    }
  }

  else if (WhileDoStmt* stmt = toWhileDoStmt(expr))
  {
    Expr* body = stmt->body.get(1);

    INT_ASSERT(stmt->body.length == 1);
    INT_ASSERT(isBlockStmt(body));

    retval = locationExpr(body, env);
  }

  else if (BlockStmt* stmt = toBlockStmt(expr))
  {
    IpeBlockStmt* ipeStmt  = (IpeBlockStmt*) stmt;
    int           maxFrame = 0;
    IpeEnv        env(ipeStmt->scopeGet());

    for (int i = 1; i <= ipeStmt->body.length; i++)
    {
      int localSize = locationExpr(ipeStmt->body.get(i), &env);

      if (localSize > maxFrame)
        maxFrame = localSize;
    }

    retval = maxFrame;
  }

  else
  {
    AstDumpToNode logger(stdout, 3);

    printf("   locationExpr(Expr*, IpeEnv* env)  unsupported\n");
    printf("   ");
    expr->accept(&logger);
    printf("\n\n");

    env->describe(3);
    printf("\n\n");

    INT_ASSERT(false);
  }

  return retval;
}
예제 #14
0
파일: view.cpp 프로젝트: DawidvC/chapel
static void
list_ast(BaseAST* ast, BaseAST* parentAst = NULL, int indent = 0) {
  bool do_list_line = false;
  bool is_C_loop = false;
  const char* block_explain = NULL;
  if (Expr* expr = toExpr(ast)) {
    if (ForallStmt* pfs = toForallStmt(parentAst)) {
      if (expr == pfs->fRecIterIRdef) {
        printf("fRecIterIRdef");
      } else if (expr == pfs->loopBody()) {
        if (pfs->numShadowVars() == 0)
          print_on_its_own_line(indent, "with() do\n");
        else
          print_on_its_own_line(indent, "do\n", false);
        indent -= 2;
      }
    }
    do_list_line = !parentAst || list_line(expr, parentAst);
    if (do_list_line) {
      printf("%-7d ", expr->id);
      print_indent(indent);
    }
    if (const char* expl = forall_explanation_start(ast, parentAst))
      printf("%s", expl);
    if (GotoStmt* e = toGotoStmt(ast)) {
      printf("goto ");
      if (SymExpr* label = toSymExpr(e->label)) {
        if (label->symbol() != gNil) {
          list_ast(e->label, ast, indent+1);
        }
      } else {
        list_ast(e->label, ast, indent+1);
      }
    } else if (toBlockStmt(ast)) {
      block_explain = block_explanation(ast, parentAst);
      const char* block_kind = ast->astTagAsString();
      if (!strcmp(block_kind, "BlockStmt")) block_kind = "";
      printf("%s{%s\n", block_explain, block_kind);
    } else if (toCondStmt(ast)) {
      printf("if ");
    } else if (toIfExpr(ast)) {
      printf("IfExpr ");
    } else if (toForallStmt(ast)) {
      printf("forall\n");
    } else if (CallExpr* e = toCallExpr(expr)) {
      if (e->isPrimitive(PRIM_BLOCK_C_FOR_LOOP))
          is_C_loop = true;
      if (e->primitive)
        printf("%s( ", e->primitive->name);
      else
        printf("call( ");
    } else if (ForallExpr* e = toForallExpr(expr)) {
      if (e->zippered) printf("zip ");
      printf("forall( ");
    } else if (NamedExpr* e = toNamedExpr(expr)) {
      printf("%s = ", e->name);
    } else if (toDefExpr(expr)) {
      Symbol* sym = toDefExpr(expr)->sym;
      if (sym->type != NULL) {
        printf("def %s ", sym->qualType().qualStr());
      } else {
        printf("def ");
      }
    } else if (SymExpr* e = toSymExpr(expr)) {
      list_sym(e->symbol(), false);
    } else if (UnresolvedSymExpr* e = toUnresolvedSymExpr(expr)) {
      printf("%s ", e->unresolved);
    } else if (isUseStmt(expr)) {
      printf("use ");
    }
  }

  if (Symbol* sym = toSymbol(ast))
    list_sym(sym);

  bool early_newline = toFnSymbol(ast) || toModuleSymbol(ast);
  if (early_newline || is_C_loop)
    printf("\n");

  int new_indent = indent;

  if (isExpr(ast))
    if (do_list_line)
      new_indent = indent+2;

  AST_CHILDREN_CALL(ast, list_ast, ast, new_indent);

  if (Expr* expr = toExpr(ast)) {
    CallExpr* parent_C_loop = NULL;
    if (CallExpr* call = toCallExpr(parentAst))
      if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP))
        parent_C_loop = call;
    if (toCallExpr(expr)) {
      printf(") ");
    }
    if (toBlockStmt(ast)) {
      printf("%-7d ", expr->id);
      if (*block_explain)
        indent -= 2;
      print_indent(indent);
      if ((parent_C_loop && parent_C_loop->get(3) == expr) || *block_explain)
        printf("} ");
      else if (isDeferStmt(parentAst))
        printf("}"); // newline is coming
      else
        printf("}\n");
      if (isForallLoopBody(expr) && parentAst != NULL) {
        print_indent(indent);
        printf("        end forall %d", parentAst->id);
      }
    } else if (ForallExpr* e = toForallExpr(expr)) {
      if (e->cond) printf(") ");
      else         printf("} ");
    } else if (UseStmt* use = toUseStmt(expr)) {
      if (!use->isPlainUse()) {
        if (use->hasExceptList()) {
          printf("except ");
        } else {
          printf("only ");
        }
        bool first = true;
        for_vector(const char, str, use->named) {
          if (first) {
            first = false;
          } else {
            printf(", ");
          }
          printf("%s", str);
        }

        for (std::map<const char*, const char*>::iterator it = use->renamed.begin();
             it != use->renamed.end(); ++it) {
          if (first) {
            first = false;
          } else {
            printf(", ");
          }
          printf("%s as %s", it->second, it->first);
        }
        printf("\n");
      }
    } else if (CondStmt* cond = toCondStmt(parentAst)) {
예제 #15
0
void collectDefExprsSTL(BaseAST* ast, std::vector<DefExpr*>& defExprs) {
  AST_CHILDREN_CALL(ast, collectDefExprsSTL, defExprs);
  if (DefExpr* defExpr = toDefExpr(ast))
    defExprs.push_back(defExpr);
}
예제 #16
0
void collectDefExprs(BaseAST* ast, Vec<DefExpr*>& defExprs) {
  AST_CHILDREN_CALL(ast, collectDefExprs, defExprs);
  if (DefExpr* defExpr = toDefExpr(ast))
    defExprs.add(defExpr);
}
예제 #17
0
// returns null if this is a catch-all
DefExpr* CatchStmt::expr() const {
  return toDefExpr(_body->body.first());
}