Beispiel #1
0
// Return a reference to the given declaration.
//
// FIXME: Specialize the reference based on whether it's a variable
// or function? Also, handle all of the other things that can be
// referred to (e.g., overload sets, parameters, etc).
Expr&
make_reference(Context& cxt, Decl& d)
{
  // TODO: What other kinds of objects do we have here...
  //
  // TODO: Dispatch.
  if (Variable_decl* v = as<Variable_decl>(&d))
    return cxt.make_reference(*v);
  if (Object_parm* p = as<Object_parm>(&d))
    return cxt.make_reference(*p);
  if (Function_decl* f = as<Function_decl>(&d))
    return cxt.make_reference(*f);

  // If it's a template name, then it must almost certainly
  // refer to a function template.
  #if 0
  if (Template_decl* t = as<Template_decl>(&d)) {
    Decl& p = t->parameterized_declaration();
    if (is<Function_decl>(&p))
      return cxt.make_reference(*t);
    throw Type_error("'{}' cannot be used as an expression");
  }
  #endif

  // Here are some things that lookup can find that are not
  // valid expressions.
  //
  // TODO: Diagnose the error and point to the declaration.
  if (Type_decl* t = as<Type_decl>(&d))
    throw Type_error("'{}' is not an object or function", t->name());

  banjo_unhandled_case(d);
}
Beispiel #2
0
// Perform unqualified lookup.
Expr&
make_reference(Context& cxt, Simple_id& id)
{
  Decl_list decls = unqualified_lookup(cxt, id);
  if (decls.size() == 1)
    return make_reference(cxt, decls.front());

  // TODO: Return a reference to an overload set.
  banjo_unhandled_case(id);
}
Beispiel #3
0
// Load the value of an object corresponding to the
// given declaration.
Value
Evaluator::load(Decl const& d)
{
  // If the expression refers to an object, then produce
  // a reference to its stored value.
  if (Object_decl const* var = as<Object_decl>(&d))
    return stack.lookup(var)->second;

  // What else?
  banjo_unhandled_case(d);
}
Beispiel #4
0
// Returns a reference to the object or function corresponding
// do the declaration `d`.
//
// FIXME: If d refers to a global variable, then we may not
// have a binding for for it. We most definitely should.
Value
Evaluator::alias(Decl const& d)
{
  // If the expression refers to an object, then produce
  // a reference to its stored value.
  if (Object_decl const* var = as<Object_decl>(&d))
    return &stack.lookup(var)->second;

  // If the expression refers to a function, then produce
  // a reference to that function.
  if (Function_decl const* fn = as<Function_decl>(&d))
    return fn;

  // Is there anything else?
  banjo_unhandled_case(d);
}
Beispiel #5
0
// Expand the concept by substituting the template arguments
// throughthe concept's definition and normalizing the result.
//
// TODO: Memoize the expansions.
Cons&
expand(Context& cxt, Concept_cons& c)
{
  Concept_decl& d = c.declaration();
  Decl_list& tparms = d.parameters();
  Term_list& targs = c.arguments();

  // NOTE: Template arguments must have been checked (in kind?)
  // prior to the formation of the constraint. It's should be
  // a semantic requirement of the original check expression.
  Substitution sub(tparms, targs);

  Def& def = d.definition();
  if (Expression_def* expr = as<Expression_def>(&def))
    return expand_expr(cxt, *expr, sub);
  if (Concept_def* body = as<Concept_def>(&def))
    return expand_def(cxt, *body, sub);
  banjo_unhandled_case(def);
}
Beispiel #6
0
// Determine if e can be contextually converted to bool, and if so,
// returns the expression that produces a boolean value from `e`.
Expr&
contextual_conversion_to_bool(Context& cxt, Expr& e)
{
  Builder b(cxt);

  // Contextual conversion to bool tries to do this:
  //
  //    bool b(e);
  //
  // so we preform direct initialization.
  Expr& init = direct_initialize(cxt, b.get_bool_type(), e);

  // Based on the initializer selected, we can either
  // 1. return the converted value directly
  // 2. synthesize an object using a constructor
  // 3. invoke a user-defined conversion
  if (Copy_init* i = as<Copy_init>(&init))
    return i->expression();

  banjo_unhandled_case(init);
}
Beispiel #7
0
 Cons& operator()(Deduction_req& r)  { banjo_unhandled_case(r); }
Beispiel #8
0
 Cons& operator()(Semantic_req& r)   { banjo_unhandled_case(r); }
Beispiel #9
0
 Expr& operator()(Name& n)        { banjo_unhandled_case(n); }
Beispiel #10
0
 Cons& operator()(Cons& c)           { banjo_unhandled_case(c); }
Beispiel #11
0
 std::size_t operator()(Cons const& c) const           { banjo_unhandled_case(c); }
Beispiel #12
0
 std::size_t operator()(Expr const& e) const           { banjo_unhandled_case(e); }
Beispiel #13
0
 Expr* operator()(Expr& e)        { banjo_unhandled_case(e); }
Beispiel #14
0
 Value operator()(Expr const& e) { banjo_unhandled_case(e); }
Beispiel #15
0
 Value operator()(Type const& t) { banjo_unhandled_case(t); }
Beispiel #16
0
 void operator()(Decl const& d)        { banjo_unhandled_case(d); }