#include <string>#include <vector>#include <stdint.h>#include "libsherpa/EnumSet.hxx"#include "libsherpa/INOstream.hxx"#include "FQName.hxx"#include "LitValue.hxx"#include "Environment.hxx"#include "debug.hxx"#include "shared_ptr.hxx"#include <libsherpa/LexLoc.hxx>#include <libsherpa/LToken.hxx>Go to the source code of this file.
| #define AST_LOCATION_TYPE sherpa::LexLoc |
| #define AST_LOCATION_TYPE sherpa::LexLoc |
| #define AST_TOKEN_TYPE sherpa::LToken |
| #define AST_TOKEN_TYPE sherpa::LToken |
| typedef sherpa::EnumSet<AstFlagValues> AstFlags |
| typedef sherpa::EnumSet<PrintFlagValues> PrintFlags |
| enum AstFlagValues |
| NO_FLAGS | |
| ID_IS_GLOBAL | Identifier is bound in type-level scope. |
| ID_IS_GENSYM | Identifier was internally generated by the compiler. |
| SELF_TAIL | Set in the tail recursion analysis pass to indicate that a use-occurrence of an identifier is a reference to the function currently being defined. Consulted in the SSA pass to add an LB_IS_DUMMY marker to the emitted let binding. Consulted in the gen-c pass to determine when looping rather than recursion should be used. |
| LB_IS_DUMMY |
The SSA pass constructs some dummy let bindings. This is used to mark them so that no assignment for them will later be emitted in the code generator. The SSA pass uses a trick to convert expression style code into statement style code. For example, in the expression (if e1 e2 e3), if E1, E2 and E3 are SSA converted forms of e1, e2 and e3 respectively, the SSA converter will produce (let* ((temp ((if E1 (let* ((temp E2)) temp) (let* ((temp E3)) temp))))) ... rest of the code will use temp as the value of if-expr ... Here, for the BitC resolver's point of view, the inner temp is different from the outer temp. So, it will resolve and type check corectly. The outer temp will have the result of the appropriate inner temp. From the C code generator's point of view, we will ignore the outer let* binding, since we cannot bind the result of if-statements. This outer let* binding is therefore marked LB_IS_DUMMY. The code generator will only declare one local variable temp, and assign the result of the correct brach to it. The rest of the code after the if statement is fine since it just knows to use the name temp, which now stores the correct value. |
| LB_POSTPONED | Do not emit an assignment for this let binding. This is a special case similar to LB_IS_DUMMY. It is generated for like array, vector, etc., which should be ignored by the code generator, as the initialization will follow in a loop. |
| ID_IS_PRIVATE | Indicates a global identifier that is not exported from its defining unit of compilation. These are emitted by the back end with a static marker to enable later optimization by the C compiler. |
| DEF_IS_ENTRYPT | Marks a definition that is an external program entry point, and therefore a seed for polyinstantiation. |
| LB_REC_BIND | Marks a let binding as a member of a letrec. This is consulted in Symtab.cxx and TypeInfer.cxx to determine whether the bound identifier should be bound early or late. If it were someday useful, this could be eliminated by introducing a distinct at_letrecbinding. |
| DEF_IS_EXTERNAL |
Marks a BitC identifier as already having an external name, which should be used during code generation in place of the BitC name. This flag is not redundant in light of the externalName field. DEF_IS_EXTERNAL is marked for all external definitions, whether it has an external name or not only some external definitions have a external-name. |
| ENUM_UN |
Used to mark a union consisting exclusively of constant legs, which is really an enum declaration. Marking is performed in TypeInfer, and is consulted in Type-size.cxx.
|
| SINGLE_LEG_UN |
Marks a union having only a single leg.
|
| CARDELLI_UN | Marks a union that is subject to one of the required Cardelli optimizations. |
| NULLABLE_UN | Marks the NULLABLE union, which has a special representation known to the code generator. |
| ID_FOR_USWITCH |
Marks the place-holder identifier that is introduced in the at_usw_leg AST to replicate the (switch ...) temporary identifier. This flag ensures that an identifier that stores a de-constructed value in a switch statement can only appear on the left of a select (.) operator. The specification enforces this rule so that the de-constructed value does not escape as a whole (as a return value, by assignment or closure). |
| ID_IS_CAPTURED | Identifier is closed over by something. |
| ID_IS_CLOSED |
Marks identifiers that are closed over by some lambda. Only use occurences that actually lie within an enclosing lambda are marked with this flag. |
| ID_NEEDS_HEAPIFY | ID must be moved to the heap due to capture. |
| ID_IS_MUTATED |
Mark if an identifier is shalowly mutated in the local context.
The flag is set if the identifier is a target of a set!. This information is used in heuristic type inference. |
| ID_MUT_CLOSED |
Mark if the identifier's ID_IS_MUTATED flag can still be updated.
This flag ensures the global identifiers' mutability is not affected by usage beyond its definition. In the case of global definitions, the identifier's mutability is marked closed, at the end of its definition. |
| PROCLAIM_IS_INTERNAL | Marked on proclaimations generated by the compiler (ex: during closure conversion). The symbol resolver warns about local proclaimations in source modules without definitions. The flag indicates that such warnings must not be produced for compiler generated proclaimations. |
| DEF_IS_TRIVIAL_INIT |
Initialization for this def can be implemented directly by the C compiler.
Set in the SSA pass to identify trivial initializers so that the code generator can avoid adding code in the per-UoC init procedure. |
| IDENT_MANGLED |
Identifier has already been mangled.
Used in the instantiator to indicate identifiers that have already been mangled and should not be mangled a second time.
|
| LOCAL_NOGEN_VAR |
Local, non-generalizable variable.
Marked for variables defined at non-generalizable boundaries. ex: Lambda parameters, identifiers defined at switch/catch, etc. Local generalizable variables must be handled by creating a new let-binding with all concrete instantiations. Non-generalizable locals like lambda-parameters, identifier at switch, catch, do, etc. can be trivially handled by performing a name change to a canonical one. |
| LBS_PROCESSED |
Used internally to track variable scoping.
This flag is used in determining the outermost let-binding at which a type variable used (scoped). The actual pointer to the let-binding is preset in tvarLB field. This flag is set on at_letbinding once we are done processing it in the symbol resolver. When we encounter the use of a type variable, if we have finished processing the let-binding named by its tvarLB field, then we know that the scope of the variable is actually bigger, and thus update it. |
| ID_OBSERV_DEF | Identifier is observably defined. |
| TVAR_POLY_SPECIAL |
Type variable that was temporarily created by the polyinstantiator.
The symbol resolver accepts type variables as defining occurences within expressions only at certain positions (when called with NEW_TV_OK). For example, this is legal within value definitions, but type variables not identified as arguments to type definitions are legal within the type definition itself. This flag marks type variables created by the polyinstantiator that must not be subject to the NEW_TV_OK check by the resolver, since the Instantiator makes some quasi RandTs in which this restriction might temporaroly not hold. |
| UNION_IS_REPR | Indicates that this DEFUNION is actually a DEFREPR that was converted to a union by the reprSimp pass. |
| FLD_IS_DISCM | Indicates a field that is a union discriminator (tag) field. |
| LAM_NEEDS_TRANS |
Marked on top-level at_define.
Indicates that this is a hoisted lambda for a function that has a captured closure, and we therefore need to emit a transition function. |
| INNER_REF_NDX |
Marks whether the inner_ref is indexing or selecting.
When set, it is an indexing inner_ref that is of the form (inner_ref (dup (array ..))) or (inner_ref (vector ... )) When clear, it is a selecting inner_ref that is of the form (inner_ref (dup (structv ... ))) or (inner_red (structr ... )) These two types of inner-ref must be handled differently in most passes. For example, the index argument must be independently resolved and type checked but the field argumet must not. |
| ARG_BYREF |
Parameter is by-reference.
Set in the parser to indicate that a parameter identifier is by-reference. Consulted in gen-c.cxx to determine how the corresponding C parameter should be emitted. In theory, the by-ref-ness is a part of the type, and must be obtainable from the identifier's type. However, the implementation does not encode by-ref this way. The by-ref is noted
Encoding by-ref in this way lends itself to cleaner implementation. If by-ref were to be a type constructor, we must look beyond the by-ref constructor at every r-value usage of the identifier. |
| MASK_FLAGS_FROM_USE | Set of ast flag values that must be masked from definitions when copying to use cases. |
| enum AstType |
| enum IdentType |
Different classifications of identifiers that we might encounter.
An IdentType is assigned by the resolver to each identifier AST node. There are two types of constants in this enumeration. Constants whose names are of the form id_name are identifier classifications. Each of these describes a particular type of identifier. All identifier AST nodes wll be assigned such a concrete classification.
Constants whose names are of the form idc_name are identifier categories. These describe sets of classifications that are legal in a given occurrence context. For example, a normal use occurrence of an identifier in an expression might validly resolve to id_value (normal values), id_ucon0 (union constructors having no elements, which are enumerands), or id_tcmethod (use-references to type class method identifiers). The identifier categories are primarily used in the resolver's recursive descent pass, where they specify what identifiers are legal in what positions.
| id_unresolved |
An identifier whose classification is not yet decided.
This is the constructor-time default value that is assigned to the identType field of the AST. It should not occur on any identifier AST after the symbol resolution pass, except in temporary ASTs that are introduced for expediency in various later passes and then resolved. |
| id_tvar | Type variables. |
| id_union | Union/repr name. |
| id_struct | Structure type name. |
| id_object | Object type name. |
| id_typeclass | Type class name. |
| id_tcmethod | Type class method name. |
| id_field | Structure or union constructor field name. |
| id_method | Structure or capsule method name. |
| id_interface |
Locally bound name that references the exported subset of an imported interface.
This is the local name defined in this module, not the fully qualified name. |
| id_value | An identifier defined at define, let, lambda, do, switch, case. |
| id_ucon | Union constructor having one or more argument. |
| id_ucon0 | Union constructor taking no arguments. |
| id_block | Label used in block/labeled escape. |
| idc_type |
Type, which is one of id_tvar, id_union, or id_struct. |
| idc_FIRST_CATEGORY | |
| idc_value |
Value, which is one of id_value, id_ucon0, or id_tcmethod. |
| idc_uctor |
Union constructor, which is one of id_ucon</ucode> or |
| idc_ctor |
Constructor, which is one of id_struct, id_ucon, or id_ucon0. |
| idc_apply |
An entity (value or constructor) that can be applied, which is one of id_value, id_tcmethod, id_method, id_struct, or id_ucon. |
| idc_usesel_lhs |
Any identifier that can legally appear to the left of the dot in an at_usesel ast.
This can either be a local name denoting an interface (id_interface) or a local name denoting a structure type (id_struct). id_interface id_struct id_method |
| enum PrintFlagValues |
| pf_NONE | |
| pf_IMPLIED |
This AST was inserted by the parser, and did not originate as user input.
This typically appears where an at_begin node was introduced to convert a block into a single expression. |
| pf_PARENWRAP | In the block syntax, indicates an expression tree that must be pretty-printed within parenthesis to preserve operator precedence. |
| std::string identTypeToString | ( | IdentType | id | ) |
Produces a printable string corresponding to the values in the above enumeration.
Definition at line 633 of file ASTimpl.cxx.
References id_block, id_field, id_interface, id_method, id_object, id_struct, id_tcmethod, id_tvar, id_typeclass, id_ucon, id_ucon0, id_union, id_unresolved, id_value, idc_apply, idc_ctor, idc_type, idc_uctor, idc_usesel_lhs, and idc_value.
1.4.7