Skip to content

scopes

record ScopedName

A name a declaration puts in a scope: the node it is reported at, the declaration’s label (what a use of the name refers to) and the name.

def Scopes.named (n : NodeId) (x : DeclId) (name : String) : List ScopedName

The name name declared by the declaration labelled x at n, none when it is unnamed.

def Scopes.bound (n : NodeId) (names : List Binder) : List ScopedName

The names a structured binding declares, at its node n.

def Scopes.declares (s : Stmt) : List ScopedName

The names the statement s declares in the block it is directly in.

def Scopes.parameters (n : NodeId) (ps : List Param) : List ScopedName

The names of the parameters ps, at the node n of what declares them.

def Scopes.twice (seen : List String) (ds : List ScopedName) : Option (NodeId * Refusal)

The first name declared twice among the names ds in one scope, after the names seen before them: the later declaration.

def Scopes.inBlock (outer : List ScopedName) (ss : List Stmt) : Option (NodeId * Refusal)

The first name declared twice in a block of statements ss, with the names outer already in its scope.

def Scopes.outermost (outer : List ScopedName) (s : Stmt) : Option (NodeId * Refusal)

The first name declared twice in the outermost block of the statement s, with the names outer already in its scope (none when it is not a block).

def Scopes.clauseStatements (cls : List Clause) : List Stmt

The statements of a switch’s clauses cls: one block.

def Scopes.inFunctionBody (forInBody : Bool) (n : NodeId) (ps : List Param) (body : Stmt) : Option (NodeId * Refusal)

The first name declared twice in a function with parameters ps declared at n and its body: the parameters are in the body‘s outermost block, and in a function-try-block’s handlers’ too (forInBody as for Scopes.inStatement).

def Scopes.inFunction (forInBody : Bool) (f : FunctionDefinition) : Option (NodeId * Refusal)

The first name declared twice in the function f (forInBody as for Scopes.inStatement).

def Scopes.inMembers (forInBody : Bool) (ms : List Member) : Option (NodeId * Refusal)

The first name declared twice in a class’s members ms: its member functions, constructors and destructor (and its nested classes’; forInBody as for Scopes.inStatement).

def Scopes.inClass (forInBody : Bool) (d : ClassDefinition) : Option (NodeId * Refusal)

The first name declared twice in the class d (forInBody as for Scopes.inStatement).

def Scopes.inItems (forInBody : Bool) (items : List Item) : Option (NodeId * Refusal)

The first name declared twice in a block scope of the items: functions, function templates, classes and class templates, at the outermost level and in namespaces (forInBody as for Scopes.inStatement).

def Scopes.firstRedeclared (rules : Rules) (items : List Item) : Option (NodeId * Refusal)

The first name a program’s items declare twice in one block scope, as the rules say a for’s scope is.

data Referent

What a name in scope refers to: a declaration, by its label; a data member of the class whose member function the name is in (an implicit this->, C++ [class.mfct.non.static]p2); or a static member function of a class, by its full name through the namespaces and classes around it (ns::D::f, Outer::Inner::f: the function a C++ checker lowers it to, [class.static.mfct]).

def NameScope : Type

The names in scope, the innermost first, each with what it refers to.

def NameScope.with (ds : List ScopedName) (scope : NameScope) : NameScope

The scope with the declarations ds added (inside the ones it has).

def NameScope.lookup (scope : NameScope) (name : String) : Option Referent

What name refers to in the scope: the innermost declaration of it.

def Scopes.enumerators (cs : List Enumerator) : List ScopedName

The names the enumerators cs declare (an enumeration constant is named by its declaration’s label).

def Scopes.visibleAfter (s : Stmt) : List ScopedName

The names the statement s puts in the scope of the statements after it in its block: what it declares, and the constants of an enumeration it defines.

record Resolving

What resolving a program’s names needs besides the scopes: whether it is C++, the names of the functions it defines (a name no scope declares that names one is that function, as a value), its classes (for the members of base classes), the namespaces the items being resolved are in, each followed by :: (a::b::; empty at file scope: a class’s static member functions are named through them), and whether they are a class template’s (its static member functions are its instances’, not functions of their own).

def Resolving.stream (n : NodeId) (name : String) : Option Expr

A standard stream written by its name in C++, with or without std:: (std::cin, cout): the stream at n.

def Resolving.unbound (r : Resolving) (n : NodeId) (name : String) : Expr

A name at n that no scope declares: a function the program defines, as a value; else a name the program’s environment may declare (a header’s constant, a board’s object, C++’s standard streams as operands), which the checker looks up and otherwise rejects as undeclared at n. r is what resolving needs besides the scopes.

def Resolving.streamObject (r : Resolving) (e : Expr) : Expr

An expression e with, in C++, the object of a member function’s call that names a standard stream (cin.ignore(), cout.flush()) as the console’s stream (eStdin, eStdout, eStderr), as a front end that resolves its names writes it; a stream elsewhere stays the name (eConst "cout": ostream_iterator<int>(cout, " "), an argument bound to std::ostream &), since the console’s stream as an operand is C’s FILE * (fgets(line, n, stdin)). r is what resolving needs besides the scopes.

def Scopes.name (r : Resolving) (scope : NameScope) (e : Expr) : Expr

A name written in an expression e, resolved in the scope (other expressions as they are, but a C++ standard stream as a member call’s object, Resolving.streamObject). r is what resolving needs besides the scopes.

def Scopes.mapIn (r : Resolving) (scope : NameScope) : SyntaxMap

Resolving the names in expressions in the scope. r is what resolving needs besides the scopes.

def Scopes.expression (r : Resolving) (scope : NameScope) (e : Expr) : Expr

An expression e with its names resolved in the scope. r is what resolving needs besides the scopes.

def Scopes.expressions (r : Resolving) (scope : NameScope) (es : List Expr) : List Expr

Expressions es with their names resolved in the scope. r is what resolving needs besides the scopes.

def Scopes.expressionOption (r : Resolving) (scope : NameScope) (e : Option Expr) : Option Expr

An optional expression e with its names resolved in the scope. r is what resolving needs besides the scopes.

def Scopes.type (r : Resolving) (scope : NameScope) (t : TypeSyntax) : TypeSyntax

A written type t with the names in it resolved in the scope (an array’s length written as an expression). r is what resolving needs besides the scopes.

def Scopes.fields (r : Resolving) (scope : NameScope) (fs : List Field) : List Field

Members of a struct or union fs with the names in their types resolved in the scope. r is what resolving needs besides the scopes.

def Scopes.structDefinition (r : Resolving) (scope : NameScope) (d : StructDefinition) : StructDefinition

A struct or union’s definition d with the names in its members’ types resolved in the scope. r is what resolving needs besides the scopes.

def Scopes.parametersIn (r : Resolving) (scope : NameScope) (ps : List Param) : List Param

Parameters ps with the names in their default arguments resolved in the scope (outside the function: a default argument may not use the parameters, C++ [dcl.fct.default]p9), and those in their types in the scope with the parameters before each (void f(int n, int a[n]), C11 6.2.1p4: a parameter’s scope starts at its declarator). r is what resolving needs besides the scopes.

def Scopes.enumeratorsIn (r : Resolving) (scope : NameScope) (cs : List Enumerator) : List Enumerator

Enumerators cs with the names in their values resolved: each value sees the scope and the enumerators before it. r is what resolving needs besides the scopes.

def Scopes.function (r : Resolving) (scope : NameScope) (f : FunctionDefinition) : FunctionDefinition

A function f with its names resolved in the scope: its parameters are in its body. r is what resolving needs besides the scopes.

def Resolving.inNamespace (r : Resolving) (name : String) : Resolving

What resolving needs (r, outside it) inside the namespace name of the items being resolved.

def Resolving.fullName (r : Resolving) (name : String) : String

A class’s full name, from its name as written or declared: as it is when qualified (a base ns::Base), else through the namespaces the items are in (Resolving.within). r is what resolving needs besides the scopes.

def Scopes.within (before : String) (name : String) : String

before::name, or name when before is empty.

def Scopes.memberNames (r : Resolving) (full : String) (ms : List Member) : NameScope

The names the members ms of the class whose full name is full put in its scope: a data member as itself (through this), a static data member and an enumerator of the class by their declarations, a static member function as the function full::f (not in a class template’s, Resolving.inTemplate). r is what resolving needs besides the scopes.

def Resolving.classNamed (r : Resolving) (name : String) : Option ClassDefinition

The class named name among the program’s classes. r is what resolving needs besides the scopes.

def Scopes.classNames (r : Resolving) (fuel : Nat) (full : String) (d : ClassDefinition) : NameScope

The names of the members of the class d (whose full name is full) and then of its bases’ (a member of the class hides one of a base, C++ [class.member.lookup]); a base the program does not define (a template’s dependent one) adds none ([temp.dep]p3). fuel bounds the depth of bases. r is what resolving needs besides the scopes.

def Resolving.depth (r : Resolving) : Nat

How deep bases may go (Scopes.classNames): one more than the program’s classes (r’s).

def Scopes.qualifiedBy (written : String) (outside : Bool) (names : NameScope) : NameScope

A class’s names names (Scopes.classNames) written through it as written: written::n ([class.qual]p1, a static member, an enumerator, a member found in a base); outside: as code outside the class’s member functions sees them, where a non-static data member is not one.

def Scopes.qualifiedNames (r : Resolving) (d : ClassDefinition) : NameScope

The names of the class d (and of the classes nested in it) written through it from outside it, as the items after it see them: C::n, C::f, Outer::Inner::k (C++ [class.qual]p1). r is what resolving needs besides the scopes.

def Scopes.classScope (r : Resolving) (scope : NameScope) (full : String) (d : ClassDefinition) : NameScope

The scope of the members of the class d, whose full name is full: its names (Scopes.classNames), also written through it (C::n, and C::field for a non-static data member, in a member function the object’s), and its nested classes’ written through them (Inner::k, C::Inner::k), inside the scope around it. r is what resolving needs besides the scopes.

def Scopes.memberInits (r : Resolving) (scope : NameScope) (inits : List MemberInit) : List MemberInit

A constructor’s member initializers inits with their names resolved in scope (the class’s, with the constructor’s parameters); r is what resolving needs besides the scopes.

def Scopes.members (r : Resolving) (full : String) (scope : NameScope) (ms : List Member) : List Member

The members ms of the class whose full name is full with their names resolved in the class’s scope; a constructor’s parameters are in its member initializers and body; a nested class’s members see its own names, then the class’s. r is what resolving needs besides the scopes.

def Scopes.classDefinition (r : Resolving) (scope : NameScope) (d : ClassDefinition) : ClassDefinition

A class d with its names resolved: its members’ bodies and initializers see the whole class (C++ [class.mem]p6), then the scope around it. r is what resolving needs besides the scopes.

def Scopes.lastPart (name : String) : String

The part of a qualified name after its last :: (a::b::x is x).

def Scopes.namespaceNames (namespaces : List (String * NameScope)) (ns : String) : NameScope

The names the namespace ns declares, which using namespace ns makes visible unqualified, from the namespaces defined before (each a name and the names it declares).

def Scopes.namespacesAfter (r : Resolving) (it : Item) (namespaces : List (String * NameScope)) : List (String * NameScope)

The namespaces defined so far, with the one the item it defines. r is what resolving needs besides the scopes.

def Scopes.qualifiers (within : String) : List String

The ways the namespaces within (a::b::) are written before a name declared in them, from inside them: a::b:: and b:: (a::b::x and b::x name x there too, C++ [namespace.qual]); none at file scope.

def Scopes.withQualified (within : String) (names : NameScope) : NameScope

The names names declared in the namespaces within, also as written through them (Scopes.qualifiers).

def Scopes.scopeAfter (r : Resolving) (namespaces : List (String * NameScope)) (scope : NameScope) (it : Item) : NameScope

The scope of the items after the item it (the namespaces defined before it): the names it declares (in a namespace, also written through it, Scopes.withQualified), the names of a namespace a using namespace names, and the one name a using-declaration names (using ns::x;). r is what resolving needs besides the scopes.

def Scopes.withNested (d : ClassDefinition) : List ClassDefinition

The class d and the classes its members define.

def Scopes.isName (e : Expr) : Bool

Whether the expression e is a name to resolve.

def Scopes.resolved (lang : Language) (items : List Item) : List Item

The program’s items with every name written (eName) resolved by the scopes it is in (as the lang says): to the declaration it names (eVar), a data member of the class (eSelf), or what no scope declares (Resolving.unbound). Items without names to resolve are as they are.