Esempio n. 1
0
void
Pipeline_checker::check_progression(Stage_set const& branches)
{
  for (auto b : branches) {
    // If at any point we branch to a node we've already visited,
    // there's a possibility a loop exists.
    if (b->visited) {
      std::stringstream ss;
      ss << "Pipeline progress goes backwards through potential loop. Broken path: ";
      for (auto stage : path)
        ss << *stage->decl()->name() << " | ";

      ss << *b->decl()->name();

      throw Lookup_error({}, ss.str());
    }

    // If we advance to a table, confirm that the table is
    // one with a higher number than our current highest.
    if (b->is_table())
      if (b->table()->number() <= highest_table) {
        std::stringstream ss;
        ss << "Pipeline path goes backwards through prior numbered table. Broken path: ";
        for (auto stage : path)
          ss << *stage->decl()->name() << " | ";

        ss << *b->decl()->name();

        throw Lookup_error({}, ss.str());
      }
  }
}
Esempio n. 2
0
Type&
Parser::on_type_name(Token tok)
{
  Simple_id& id = build.get_id(tok);
  Decl& decl = simple_lookup(cxt, current_scope(), id);
  if (Type* type = get_type_for_decl(cxt, decl))
    return *type;
  throw Lookup_error("'{}' does not name a type", id);
}
Esempio n. 3
0
// FIXME: What if the identifier refers to a set of declarations?
Decl&
Parser::on_concept_name(Token tok)
{
  Simple_id& id = build.get_id(tok);
  Decl& decl = simple_lookup(cxt, current_scope(), id);
  if (is<Concept_decl>(&decl))
    return decl;
  throw Lookup_error("'{}' does not name a concept", id);
}
Esempio n. 4
0
// Check if the template-id n refers to a type.
Type&
Parser::on_type_name(Name& n)
{
  Template_id& id = cast<Template_id>(n);
  Template_decl& tmp = id.declaration();
  Term_list& args = id.arguments();
  Decl& decl = specialize_template(cxt, tmp, args);
  if (Type* type = get_type_for_decl(cxt, decl))
    return *type;
  throw Lookup_error("not a type name");
}
Esempio n. 5
0
Type const*
Elaborator::elaborate(Id_type const* t)
{
  Scope::Binding const* b = stack.lookup(t->symbol());
  if (!b) {
    std::stringstream ss;
    ss << "no matching declaration for '" << *t->symbol() << '\'';
    throw Lookup_error(locs.get(t), ss.str());
  }

  // Determine if the name is a type declaration.
  Decl* d = b->second;
  if (Record_decl* r = as<Record_decl>(d)) {
    return get_record_type(r);
  }
  else {
    std::stringstream ss;
    ss << '\'' << *t->symbol() << "' does not name a type";
    throw Lookup_error(locs.get(t), ss.str());
  }
}
Esempio n. 6
0
Type&
Parser::on_type_alias(Token tok)
{
  Simple_id& id = build.get_id(tok);
  Decl& decl = simple_lookup(cxt, current_scope(), id);

  if (Type_parm* d = as<Type_parm>(&decl))
    return build.get_typename_type(*d);

  // TODO: Actually support type aliases.

  throw Lookup_error("'{}' does not name a type", id);
}
Esempio n. 7
0
// Perform qualified lookup to resolve the declaration referred to by obj.n.
//
// FIXME: This needs to perform class lookup, not qualified lookup.
static Expr&
make_member_ref(Context& cxt, Expr& obj, Simple_id& name)
{
  Type& type = obj.type();
  Decl_list decls = qualified_lookup(cxt, type, name);
  if (decls.empty()) {
    error(cxt, "no matching declaration for '{}'", name);
    throw Lookup_error();
  }
  if (decls.size() == 1)
    return make_resolved_mem_ref(cxt, obj, decls.front());
  else
    return make_mem_overload_ref(cxt, obj, name, std::move(decls));
}
Esempio n. 8
0
// Create a declarative binding for d. This also checks
// that the we are not redefining a symbol in the current
// scope.
void
Scope_stack::declare(Decl* d)
{
  Scope& scope = current();

  // TODO: If we allow overloading, then this is
  // where we would handle that.
  if (scope.lookup(d->name())) {
    // TODO: Add a note that points to the previous
    // definition.
    std::stringstream ss;
    ss << "redefinition of '" << *d->name() << "'\n";
    throw Lookup_error({}, ss.str());
  }

  // Create the binding.
  scope.bind(d->name(), d);

  // Set d's declaration context.
  d->cxt_ = context();
}
Esempio n. 9
0
// Elaborate an id expression. When the identifier refers
// to an object of type T (a variable or parameter), the
// type of the expression is T&. Otherwise, the type of the
// expression is the type of the declaration.
//
// TODO: There may be some contexts in which an unresolved
// identifier can be useful. Unfortunately, this means that
// we have to push the handling of lookup errors up one
// layer, unless we to precisely establish contexts where
// such identifiers are allowed.
Expr*
Elaborator::elaborate(Id_expr* e)
{
  Scope::Binding const* b = stack.lookup(e->symbol());
  if (!b) {
    std::stringstream ss;
    ss << "no matching declaration for '" << *e->symbol() << '\'';
    throw Lookup_error(locs.get(e), ss.str());
  }

  // Annotate the expression with its declaration.
  Decl* d = b->second;
  e->declaration(d);

  // If the referenced declaration is a variable of
  // type T, then the type is T&. Otherwise, it is just T.
  Type const* t = d->type();
  if (defines_object(d))
    t = t->ref();
  e->type(t);

  return e;
}
Esempio n. 10
0
void
Pipeline_checker::check_stage(Decl const* d, Sym_set const& reqs)
{
  bool error = false;
  std::stringstream ss;

  for (auto field : reqs) {
    auto search = stack.lookup(field);
    if (!search) {
      error = true;
      ss << "Field " << *field
         << " required but not decoded.\n";
    }
  }

  if (error) {
    ss << "Broken path: ";
    for (auto stage : path) {
      ss << *stage->decl()->name() << " | ";
    }

    throw Lookup_error({}, ss.str());
  }
}
Esempio n. 11
0
Type&
Parser::on_enum_name(Name&)
{
  throw Lookup_error("not an enum");
}
Esempio n. 12
0
Decl&
Parser::on_namespace_alias(Name&)
{
  throw Lookup_error("not a namespace alias");
}
Esempio n. 13
0
Decl&
Parser::on_namespace_name(Name&)
{
  throw Lookup_error("not a namespace");
}
Esempio n. 14
0
Decl&
Parser::on_namespace_name(Token id)
{
  throw Lookup_error("not a namespace");
}
Esempio n. 15
0
Type&
Parser::on_type_alias(Name&)
{
  throw Lookup_error("not a type alias");
}
Esempio n. 16
0
Type&
Parser::on_union_name(Name&)
{
  throw Lookup_error("not a union");
}
Esempio n. 17
0
Type&
Parser::on_class_name(Name&)
{
  throw Lookup_error("not a class");
}