Skip to content

operators

def Operators.classOf (g : Globals Cpp.constructs) (l : Lifted Cpp.constructs) : Option ClassMembers

The class of a checked expression’s type (through a reference), if it is one.

def Operators.hasFunction (g : Globals Cpp.constructs) (f : String) : Bool

Whether the program has a function of a name (overloaded or not).

def Operators.hasMember (g : Globals Cpp.constructs) (c : ClassMembers) (f : String) : Bool

Whether a class (or a base) has a member of a name.

def Operators.declared (g : Globals Cpp.constructs) (name : String) : Bool

Whether the program has an operator function of a name at all: a function, or a member of some class (when it has none, an operator is not a call, and its operands need no checking here: checking them at every level of a nested expression costs as much as the expression’s size times its depth).

def Operators.lastQualifier (depth : Nat) (at : Nat) (last : Option Nat) (cs : List Char) : Option Nat

Where the last :: outside template arguments starts in the characters (depth: the arguments open, at: where the characters start).

def Operators.namespaceOf (x : String) : String

The namespace a class’s name is in, with its :: (empty for none): up to the last :: outside template arguments (std::vector<std::string> is in std::).

def Operators.candidates (g : Globals Cpp.constructs) (name : String) (classes : List ClassMembers) : List String

The names an operator’s function is looked up by: its own (the program’s), then in the namespaces of the operands’ classes (argument-dependent lookup, [basic.lookup.argdep]), those the program has, each once.

def Operators.chosen (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (operands : List Expr) (candidates : List String) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

An operator’s call of a function among the candidates: the one whose call checks (the first one’s failure when none does).

def Operators.mayBeClass (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (e : Expr) : Bool

Whether an expression may be an object of a class, checking only what can be: a literal is not, a built-in operator’s result on operands that are not is not, and a cast is one when its type is; anything else is checked. Checking each operand whole at every level of a nested expression (once here, once more when the operator is the core’s) costs twice per level: exponential in the depth.

def Operators.keptLeft (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (name : String) (rest : List Expr) (first : Option Kept.Checked) : Option Kept

The left operand of an operator name at the node n written as a call of the program’s function (o << x as operator<<(o, x)), checked as first (with the globals g in the scope env), kept before the rest (Classes.kept) when the built-in operator’s left operand goes first ([over.match.oper]p2, Classes.objectFirst) and it has statements of its own; else none (the operands as written, unsequenced as a call’s arguments).

def Operators.call (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (name : String) (operands : List Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

The call an operator with operands is, when one of them is an object of a class: the left one’s member, else the program’s function or one in the namespace of an operand’s class.

def Operators.index (pick : Picking) (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (e : Expr) (asLvalue : Bool) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

v[i] on an object of a class with operator[]: the call v.operator[](i).

def Operators.unmodeledStream (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (op : BinaryOp) (a : Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

The operator op at the node n whose left operand a (checked by checker with the globals g in the scope env) is an object of the model’s std::istream or std::ostream class with no function for it: unknown, not the core’s rejection. Those classes are empty in the model (their reading and writing are the stream statements, in >> x through an istream & is not provided yet), while the standard library has the operators ([istream.formatted]).

def Operators.streamOperand (env : Env Cpp.constructs) (e : Expr) : Option String

The class of a standard stream an operand e is, read from how it is written (checking an operand twice doubles the work at each level of a nested expression): cout or cerr (std::ostream’s) and cin (std::istream’s) by their names (Classes.standardStream; whether or not the model has their objects), or a variable of the class in the scope env.

def Operators.streamText (x : String) : String * String

A standard stream’s class x as clang writes it: the typedef and the class template’s instance it stands for.

def Operators.operandText (types : TypeExtension Cpp.constructs) (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (stream : Option String) (x : Expr) : CheckResult Cpp.constructs String

An operand x of a binary operator as clang writes its type: a standard stream’s (stream, its class) by Operators.streamText, else the operand’s type before it decays, written by types (the operand checked by checker with the globals g in the scope env, so an error in it comes first).

def Operators.streamMismatch (types : TypeExtension Cpp.constructs) (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (e : Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

A binary operator e with a standard stream for an operand (Operators.streamOperand) that neither std::ostream nor std::istream has (cout < "Hello!", cin < x, x == cin; [ostream] and [istream] declare <<, >> and the conversion to bool that && and || use): clang’s error, the operands’ types as written (Refusal.operandTypes, a stream’s with what it stands for, Operators.operandText by types), after an error in an operand, which clang reports first (checked by checker with the globals g in the scope env). A program declaring the operator’s function may have one for a stream (Operators.call), looked up only once an operand is a stream: every binary operator comes here, and resolving its function for an operand that is not a stream checks the operands once more at each level of a nested expression. None for any other expression.

def Operators.expression (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (e : Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

C++’s operators on objects: binary and unary operators, increments and decrements as calls, a call of an object as its operator().

def Operators.memberLvalue (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (name : String) (a : Expr) (rest : List Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

An operator’s member call as an lvalue: the operand’s class declares the operator.

def Operators.functionLvalue (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (name : String) (operands : List Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

An operator name at the node n on the operands as a function’s call, as an lvalue: the call of the candidate (a function of the program, or one in the namespace of an operand’s class) whose call checks, by checker with the globals g and the variables in scope env; its result of class type is materialized (References.callLvalue). None when no operand is an object of a class or no candidate’s call checks.

def Operators.operatorLvalue (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (name : String) (a : Expr) (rest : List Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

An operator name at the node n on a (and rest) as an lvalue, checked by checker with the globals g and the variables in scope env: the left operand’s member call when its class declares the operator, else a function’s call (Operators.functionLvalue).

def Operators.lvalue (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (e : Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

C++’s operators on objects as lvalues: *a, ++a and --a as the operand’s member calls ((*it).f()); a unary or binary operator as the operand’s member call or a function’s call ((~b).to_ulong(), (b & c).count()), whose result of class type is materialized so a member function can be called on it (*(it + 1), [class.temporary]p2).

def Operators.streamClass : String

The name of std::ostream’s class and of its one object (standard output).

def Operators.standardOutput : DeclId

The variable standard output’s object is.

def Operators.isStream (t : TypeSyntax) : Bool

Whether a type is std::ostream.

def Operators.inputClass : String

The name of std::istream’s class and of its one object (standard input).

def Operators.standardInput : DeclId

The variable standard input’s object is.

def Operators.namedStream (e : Expr) : Option (NodeId * String)

The standard stream an operand e names, at its node: cout, cin or cerr, with or without std::, written as a name the environment declares (eConst; what a name the front end leaves to Cella resolves to as an operand, Resolving.streamObject). In C++ these are std::ostream’s and std::istream’s objects ([iostream.objects]); the console’s streams as operands (eStdin) are C’s FILE * (fgets(line, n, stdin)).

def Operators.standardStream (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (asLvalue : Bool) (e : Expr) : Option (CheckResult Cpp.constructs (Lifted Cpp.constructs))

A standard stream as an operand (std::ostream_iterator<int>(std::cout, " "), an argument bound to std::ostream &, Operators.namedStream): cout is the one object of std::ostream’s class (standard output’s) and cin of std::istream’s (standard input’s) when the program has the class (Operators.prepare); otherwise, and for cerr (the model writes to it only in an output statement), unknown: the model has no object for it, and the stream is not a FILE *. None for any other expression (cpp.names takes the environment’s constants). The expression e, checked by checker in the globals g and the scope env, as an lvalue when asLvalue.

def Operators.reads (e : Expr) : List Bool

Whether an expression reads standard input (std::cin >> ..., std::getline(std::cin, s)).

def Operators.isInput (t : TypeSyntax) : Bool

Whether a written type is std::istream.

def Operators.prepare (p : Program) : Program

A program using std::ostream with its class and its one object first, the type written as the class; one reading standard input or naming std::istream (the library’s operator>> of strings) with std::istream’s class and object.

def Operators.outputs (checker : Checker Cpp.constructs) (g : Globals Cpp.constructs) (env : Env Cpp.constructs) (n : NodeId) (es : List Expr) : List Stmt

An output’s items split at the objects of classes: the runs of the others written as before, each object passed to operator<< with standard output.

def Operators.statement (checker : Checker Cpp.constructs) (statements : StatementChecker Cpp.constructs) (c : StatementContext Cpp.constructs) (env : Env Cpp.constructs) (s : Stmt) : Option (CheckResult Cpp.constructs (TypedStmt Cpp.constructs))

C++’s output of objects of classes through operator<<, and an operator<<’s output to the stream it is given.