Resolution

This section contains definitions declared in the chpl::resolution namespace.

namespace resolution

Typedefs

using KindRequirement = optional<chpl::types::QualifiedType::Kind>

An optional additional constraint on the kind of a type. Used in commonType to serve the case of functions that enforce param, type, or const returns.

using PoiCallIdFnIds = std::set<std::pair<ID, ID>>
using PoiRecursiveCalls = std::set<std::pair<const TypedFnSignature*, const PoiScope*>>
using SubstitutionsMap = types::CompositeType::SubstitutionsMap

See the documentation for types::CompositeType::SubstitutionsMap.

using DeclMap = std::unordered_map<UniqueString, OwnedIdsWithName>

A DeclMap has key = string name, and value = vector of ID of a NamedDecl Using an ID here prevents needing to recompute the Scope if (say) something in the body of a Function changed.

using LookupConfig = unsigned int

LookupConfig is a bit-set of the LOOKUP_ flags defined above

using ScopeSet = llvm::SmallPtrSet<const Scope*, 5>
using CheckedScopes = std::unordered_map<CheckedScope, IdAndFlags::FlagSet>

Enums

enum SkipCallResolutionReason

In some situations, we may decide not to resolve a call. This could happen if we believe it to already be ill-formed (e.g., why would we resolve f(x) if x is ill-typed?

This enum contains reasons why we might want that to do that.

Values:

enumerator NONE
enumerator UNKNOWN_PARAM
enumerator GENERIC_TYPE
enumerator GENERIC_VALUE
enumerator UNKNOWN_ACT
enumerator ERRONEOUS_ACT
enumerator OTHER_REASON
enum class DefaultsPolicy

Values:

enumerator IGNORE_DEFAULTS

Do not use default values when determining field type.

enumerator USE_DEFAULTS

Use default values when determining field type.

enumerator USE_DEFAULTS_OTHER_FIELDS

Do not use default values for the current field (i.e. when set up for resolving a field statement), but do use default values for all other fields. This policy is useful when determining the genericity of individual fields.

enum CandidateFailureReason

An enum that represents the reason why a function candidate was filtered out during call resolution.

Values:

enumerator FAIL_CANNOT_PASS
enumerator FAIL_FORMAL_ACTUAL_MISMATCH
enumerator FAIL_VARARG_MISMATCH
enumerator FAIL_WHERE_CLAUSE
enumerator FAIL_PARENLESS_MISMATCH
enumerator FAIL_CANDIDATE_OTHER
enum PassingFailureReason

An enum that represents the reason why an actual couldn’t be passed to a formal.

Values:

enumerator FAIL_INCOMPATIBLE_NILABILITY
enumerator FAIL_INCOMPATIBLE_MGMT
enumerator FAIL_INCOMPATIBLE_MGR
enumerator FAIL_EXPECTED_SUBTYPE
enumerator FAIL_INCOMPATIBLE_TUPLE_SIZE
enumerator FAIL_INCOMPATIBLE_TUPLE_STAR
enumerator FAIL_CANNOT_CONVERT
enumerator FAIL_CANNOT_INSTANTIATE
enumerator FAIL_TYPE_VS_NONTYPE
enumerator FAIL_NOT_PARAM
enumerator FAIL_MISMATCHED_PARAM
enumerator FAIL_UNKNOWN_ACTUAL_TYPE
enumerator FAIL_UNKNOWN_FORMAL_TYPE
enumerator FAIL_GENERIC_TO_NONTYPE
enumerator FAIL_NOT_EXACT_MATCH
enumerator FAIL_FORMAL_OTHER
enum VisibilityStmtKind

Values:

enumerator VIS_USE
enumerator VIS_IMPORT

Functions

template<typename ResolvedVisitorImpl>
static bool resolvedVisitorEnterFor(ResolvedVisitorImpl &v, const uast::For *loop)
template<typename ResolvedVisitorImpl>
static bool resolvedVisitorEnterAst(ResolvedVisitorImpl &v, const uast::AstNode *ast)
static inline CanPassResult canPass(Context *context, const types::QualifiedType &actualType, const types::QualifiedType &formalType)

Given an argument with QualifiedType actualType, can that argument be passed to a formal with QualifiedType formalType?

Note that a result with passes() and instantiates() indicates that the compiler should try instantiating. Once instantiation occurs, the compiler may figure out that the argument cannot be passed.

optional<chpl::types::QualifiedType> commonType(Context *context, const std::vector<chpl::types::QualifiedType> &types, KindRequirement requiredKind = KindRequirement())

Given a (non-empty) list of types (e.g., the types of various return statements in a function), determine the type, if any, that can be used to represent all of them. Returns an optional that contains the qualified type if one is found, or is empty otherwise.

If useRequiredKind=true is specified, the requiredKind argument is treated as a strict constraint on the kinds of the given types. For instance, specifying requiredKind=PARAM and giving non-param types will result in failure to find a common type, even if the types can otherwise by unified.

std::set<ID> computeElidedCopies(Context *context, const uast::AstNode *symbol, const ResolutionResultByPostorderID &byPostorder, const PoiScope *poiScope, const std::set<ID> &allSplitInitedVars, types::QualifiedType fnYieldedType)
MostSpecificCandidates findMostSpecificCandidates(Context *context, const CandidatesAndForwardingInfo &lst, const CallInfo &call, const Scope *callInScope, const PoiScope *callInPoiScope)

Given the result of filterCandidatesInstantiating, run overload resolution aka disambiguation to determine the most specific functions.

If a most specific function cannot be found due to ambiguity, returns an empty MostSpecificCandidates that also tracks the fact there was an ambiguity (so it can be differentiated from no candidates).

‘lst’ contains all of the TypedFnSignatures that are candidates for the call ‘call’.

If forwarding is in use, for any candidate, ‘forwardingInfo’ contains an element for each of the candidates in ‘lst’ and stores the actual type passed to the method receiver. This indicates which ‘forwarding’ statement is in use.

types::QualifiedType::Kind resolveIntent(const types::QualifiedType &t, bool isThis, bool isInit)

Resolve the intent of a formal argument based on its type and (possibly generic) intent. For example ‘const’ is a generic intent and it has different behavior depending on the type.

The argument ‘isThis’ indicates if the formal argument is the ‘this’ method receiver argument.

The argument ‘isInit’ indicates if the function being resolved is an ‘init’ or ‘init=’ function.

The generic and resolved intents are all represented as QualifiedType::Kind.

If the type is not known or only partially known, this function can return a generic intent.

const ResolutionResultByPostorderID &resolveModuleStmt(Context *context, ID id)

Resolve a module-level statement or variable declaration.

const ResolutionResultByPostorderID &resolveModule(Context *context, ID id)

Resolve the contents of a Module

const ResolutionResultByPostorderID &scopeResolveModule(Context *context, ID id)

Resolve the contents of a Module but don’t resolve any paren-ful function calls or establish types.

const types::QualifiedType &typeForModuleLevelSymbol(Context *context, ID id, bool currentModule = false)

Compute the type for a NamedDecl with a particular id.

const types::QualifiedType &typeForBuiltin(Context *context, UniqueString name)

Compute the type for a Builtin type using just its name

types::QualifiedType typeForLiteral(Context *context, const uast::Literal *literal)

Compute the type for a literal

types::QualifiedType getInstantiationType(Context *context, types::QualifiedType actualType, types::QualifiedType formalType)

Returns the type that results when instantiating formalType, which must be generic, with actualType.

const std::map<ID, types::QualifiedType> &computeNumericValuesOfEnumElements(Context *context, ID node)

Returns a map from enum element IDs to their numeric values. The caller is responsible for validating that node is an enum ID. If an invalid ID is given, an empty map is returned.

Abstract elements are not stored in the returned map, to distinguish from non-abstract elements whose values could not be computed.

const chpl::optional<types::QualifiedType> &computeUnderlyingTypeOfEnum(Context *context, ID element)
const chpl::optional<types::QualifiedType> &computeNumericValueOfEnumElement(Context *context, ID element)

Returns the numeric value of an enum element. The caller is responsible for validating that element is an enum element ID. If an invalid ID is given, an empty optional is returned.

ID lookupEnumElementByNumericValue(Context *context, const ID &node, const types::QualifiedType &value)
const TypedFnSignature *typedSignatureInitial(Context *context, const UntypedFnSignature *untypedSig)

Compute a TypedFnSignature from an UntypedFnSignature. (An UntypedFnSignature can be computed with UntypedFnSignature::get()). The TypedFnSignature will represent generic and potentially unknown types if the function is generic.

const types::Type *initialTypeForTypeDecl(Context *context, ID declId)

Returns a Type that represents the initial type provided by a TypeDecl (e.g. Class, Record, etc). This type does not store the fields.

const ResolvedFields &resolveFieldDecl(Context *context, const types::CompositeType *ct, ID fieldId, DefaultsPolicy defaultsPolicy)

Resolve a single field decl (which could be e.g. a MultiDecl) within a CompositeType.

The result will not have summary information computed. fieldsForTypeDecl should be used instead unless there is a reason that one-at-a-time resolution is important.

const ResolvedFields &fieldsForTypeDecl(Context *context, const types::CompositeType *ct, DefaultsPolicy defaultsPolicy)

Compute the types of the fields for a CompositeType (such as one returned by initialTypeForTypeDecl).

If useGenericFormalDefaults is true, a generic field like record R { type t = int; } will be assumed to have the default value (int in the above case). Otherwise, these fields will remain generic.

Even if useGenericFormalDefaults is set, the default value will be ignored if the field already has a substitution in the CompositeType.

The returned fields do not include any parent class fields.

const types::CompositeType *isNameOfField(Context *context, UniqueString name, const types::Type *t)

If ‘name’ is the name of a field for type ‘t’, returns a non-null pointer; Otherwise, returns ‘nullptr’.

The returned pointer will point to the type containing the field. For records and unions, that will just be ‘t’. For classes, it won’t necessarily be ‘t’, since a field might come from a superclass. If the field comes from a superclass, this function will return the BasicClass type for the superclass that contains the field directly.

const types::QualifiedType typeWithDefaults(Context *context, types::QualifiedType t)

Computes the version of a type assuming that defaults for generics are needed. So, for ‘record R { type t = int; }’, this will return R(int).

types::Type::Genericity getTypeGenericityIgnoring(Context *context, const types::Type *t, std::set<const types::Type*> &ignore)

Compute whether a type is generic or not. Considers the field of a record/class. For a UnknownType, returns MAYBE_GENERIC.

Considers types in the ignore set as concrete.

types::Type::Genericity getTypeGenericityIgnoring(Context *context, types::QualifiedType qt, std::set<const types::Type*> &ignore)

Compute whether a QualifiedType is generic or not. Considers the field of a record/class. For a UnknownType, returns MAYBE_GENERIC.

Considers types in the ignore set as concrete.

types::Type::Genericity getTypeGenericity(Context *context, const types::Type *t)

Compute whether a QualifiedType is generic or not. Considers the field of a record/class. For a UnknownType, returns MAYBE_GENERIC.

types::Type::Genericity getTypeGenericity(Context *context, types::QualifiedType qt)

Compute whether a QualifiedType is generic or not. Considers the field of a record/class. For a UnknownType, returns MAYBE_GENERIC.

const TypedFnSignature *typeConstructorInitial(Context *context, const types::Type *t)

Compute an initial TypedFnSignature for a type constructor for a particular type. If some fields of t are still generic, it will be necessary to call instantiateSignature on it.

ApplicabilityResult instantiateSignature(Context *context, const TypedFnSignature *sig, const CallInfo &call, const PoiScope *poiScope)

Instantiate a TypedFnSignature from the result of typedSignatureInitial, a CallInfo describing the types at the call site, and a point-of-instantiation scope representing the POI scope of the call

const ResolvedFunction *resolveFunction(Context *context, const TypedFnSignature *sig, const PoiScope *poiScope)

Compute a ResolvedFunction given a TypedFnSignature. Checks the generic cache for potential for reuse. When reuse occurs, the ResolvedFunction might point to a different TypedFnSignature.

This function will resolve a nested function if it does not refer to any outer variables.

const ResolvedFunction *resolveInitializer(Context *context, const TypedFnSignature *sig, const PoiScope *poiScope)

Compute a ResolvedFunction given a TypedFnSignature for an initializer. The difference between this and ‘resolveFunction’ is that it is possible for the type of the receiver to still be generic (as the initializer body must be resolved before the concrete type is known).

const ResolvedFunction *resolveConcreteFunction(Context *context, ID id)

Helper to resolve a concrete function using the above queries. Will return nullptr if the function is generic or has a where false.

const ResolvedFunction *scopeResolveFunction(Context *context, ID id)

Compute a ResolvedFunction given a TypedFnSignature, but don’t do full resolution of types or paren-ful calls in the body.

const OuterVariables *computeOuterVariables(Context *context, ID id)

Compute the set of outer variables referenced by this function. Will return ‘nullptr’ if there are no outer variables.

const ResolutionResultByPostorderID &scopeResolveAggregate(Context *context, ID id)
const ResolvedFunction *resolveOnlyCandidate(Context *context, const ResolvedExpression &r)

Returns the ResolvedFunction called by a particular ResolvedExpression, if there was exactly one candidate. Otherwise, it returns nullptr.

This function does not handle return intent overloading.

const types::QualifiedType &returnType(Context *context, const TypedFnSignature *sig, const PoiScope *poiScope)

Compute the return/yield type for a function.

TODO: If the function returns a param, the param’s value may not be available. This is because the function body is not resolved when the return type is explicitly declared. We probably still want to compute the value in such cases, though.

const TypedFnSignature *inferOutFormals(Context *context, const TypedFnSignature *sig, const PoiScope *poiScope)

Compute the types for any generic ‘out’ formal types after instantiation of any other generic arguments.

‘out’ formals with concrete type will already have their types represented in the ‘sig’ passed here (through typedSignatureInitial and potentially instantiateSignature).

For the generic ‘out’ formals, their types are inferred from the body of the function.

The returned TypedFnSignature* will have the inferred out formal types.

const TypedFnSignature *inferRefMaybeConstFormals(Context *context, const TypedFnSignature *sig, const PoiScope *poiScope)

Try to compute the TypedFnSignature with REF_MAYBE_CONST formals computed as ‘ref’ or ‘const ref’. If the TypedFnSignature is currently being resolved, instead of returning a new TypedFnSignature, this function returns ‘nullptr’. In that case, the caller is responsible for attempting this again later once the current set of recursive functions is resolved.

const CandidatesAndForwardingInfo &filterCandidatesInitial(Context *context, std::vector<BorrowedIdsWithName> lst, CallInfo call)

Compute the (potentially generic) TypedFnSignatures of possibly applicable candidate functions from a list of visible functions.

void filterCandidatesInstantiating(Context *context, const CandidatesAndForwardingInfo &lst, const CallInfo &call, const Scope *inScope, const PoiScope *inPoiScope, CandidatesAndForwardingInfo &result, std::vector<ApplicabilityResult> *rejected = nullptr)

Further filter the result of filterCandidatesInitial down by doing instantiations. After this, all of the resulting TypedFnSignatures are actually candidates.

If instantiation occurs, gets/creates the new POI scope for inScope/inPoiScope.

CallResolutionResult resolveCall(Context *context, const uast::Call *call, const CallInfo &ci, const Scope *inScope, const PoiScope *inPoiScope, std::vector<ApplicabilityResult> *rejected = nullptr)

Given a uast::Call, a CallInfo representing the call, a Scope representing the scope of that call, and a PoiScope representing the point-of-instantiation scope of that call, find the most specific candidates as well as the point-of-instantiation scopes that were used when resolving them.

‘resolveCallInMethod’ should be used instead when resolving a non-method call within a method.

CallResolutionResult resolveCallInMethod(Context *context, const uast::Call *call, const CallInfo &ci, const Scope *inScope, const PoiScope *inPoiScope, types::QualifiedType implicitReceiver, std::vector<ApplicabilityResult> *rejected = nullptr)

Similar to resolveCall, but handles the implicit scope provided by a method.

When a resolving a call within a method, the implicitReceiver should be set to the ‘this’ type of the method.

If implicitReceiver.type() == nullptr, it will be ignored.

CallResolutionResult resolveGeneratedCall(Context *context, const uast::AstNode *astForErr, const CallInfo &ci, const Scope *inScope, const PoiScope *inPoiScope, std::vector<ApplicabilityResult> *rejected = nullptr)

Given a CallInfo representing a call, a Scope representing the scope of that call, and a PoiScope representing the point-of-instantiation scope of that call, find the most specific candidates as well as the point-of-instantiation scopes that were used when resolving them.

CallResolutionResult resolveGeneratedCallInMethod(Context *context, const uast::AstNode *astForErr, const CallInfo &ci, const Scope *inScope, const PoiScope *inPoiScope, types::QualifiedType implicitReceiver)

Similar to resolveGeneratedCall but handles the implicit scope provided by a method.

When a resolving a call within a method, the implicitReceiver should be set to the ‘this’ type of the method.

If implicitReceiver.type() == nullptr, it will be ignored.

const TypedFnSignature *tryResolveInitEq(Context *context, const uast::AstNode *astForScopeOrErr, const types::Type *lhsType, const types::Type *rhsType, const PoiScope *poiScope = nullptr)
const TypedFnSignature *tryResolveAssign(Context *context, const uast::AstNode *astForScopeOrErr, const types::Type *lhsType, const types::Type *rhsType, const PoiScope *poiScope = nullptr)
const TypedFnSignature *tryResolveDeinit(Context *context, const uast::AstNode *astForScopeOrErr, const types::Type *t, const PoiScope *poiScope = nullptr)
bool isTypeDefaultInitializable(Context *context, const types::Type *t)

Given a type ‘t’, compute whether or not ‘t’ is default initializable. If ‘t’ is a generic type, it is considered non-default-initializable. Considers the fields and substitutions of composite types.

CopyableAssignableInfo getCopyOrAssignableInfo(Context *context, const types::Type *t, bool checkCopyable)

Determine whether type ‘t’ is copyable/assignable from const or/and from ref. When checkCopyable is true, this checks copyability, and for false checks assignability.

const std::unordered_map<UniqueString, types::QualifiedType> &getCompilerGeneratedGlobals(Context *context)

Determine the types of various compiler-generated globals, which depend on the settings the compiler / Dyno was started with.

void reportInvalidMultipleInheritance(Context *context, const uast::Class *node, const uast::AstNode *firstParent, const uast::AstNode *secondParent)
const std::vector<const uast::Function*> &getTestsGatheredViaPrimitive(Context *context)

One of the compiler primitives has the side effect of collecting all test functions. This helper retrieves the list of test functions that has been collected.

bool createsScope(uast::AstTag tag)

Returns true if this AST type can create a scope.

const Scope *scopeForId(Context *context, ID id)

Returns the Scope for an ID.

const Scope *scopeForModule(Context *context, ID moduleId)

Given an ID for a Module, returns a Scope that represents the Module scope (and what symbols are defined in it).

std::vector<BorrowedIdsWithName> lookupNameInScope(Context *context, const Scope *scope, llvm::ArrayRef<const Scope*> receiverScopes, UniqueString name, LookupConfig config)

Find what a name might refer to.

‘scope’ is the context in which the name occurs (e.g. as an Identifier)

‘receiverScopes’ is the scope of a type containing the name, in the case of method calls, field accesses, and resolving a name within a method. It is a Scope representing the record/class/union itself for the receiver. If provided, the receiverScopes will be consulted after declarations within ‘scope’ but before its parents. It accepts multiple scopes in order to handle classes with inheritance.

The config argument is a group of or-ed together bit flags that adjusts the behavior of the lookup. Please see ‘LookupConfig’ and the related constants such as ‘LOOKUP_DECLS’ for further details.

std::vector<BorrowedIdsWithName> lookupNameInScopeWithWarnings(Context *context, const Scope *scope, llvm::ArrayRef<const Scope*> receiverScopes, UniqueString name, LookupConfig config, ID idForWarnings)

Same as lookupNameInScope but can produce warnings based on the ID passed in.

std::vector<BorrowedIdsWithName> lookupNameInScopeTracing(Context *context, const Scope *scope, llvm::ArrayRef<const Scope*> receiverScopes, UniqueString name, LookupConfig config, std::vector<ResultVisibilityTrace> &traceResult)

Same as lookupNameInScope but traces how each symbol was found, for error messages.

std::vector<BorrowedIdsWithName> lookupNameInScopeWithSet(Context *context, const Scope *scope, const llvm::ArrayRef<const Scope*> receiverScopes, UniqueString name, LookupConfig config, CheckedScopes &visited)

Same as lookupNameInScope but includes a set tracking visited scopes.

bool isWholeScopeVisibleFromScope(Context *context, const Scope *checkScope, const Scope *fromScope)

Returns true if all of checkScope is visible from fromScope due to scope containment or whole-module use statements.

const PoiScope *pointOfInstantiationScope(Context *context, const Scope *scope, const PoiScope *parentPoiScope)

Returns a unique’d point-of-instantiation scope for the passed scope and parent POI scope. Collapses away POI scopes that do not affect visible functions.

const InnermostMatch &findInnermostDecl(Context *context, const Scope *scope, UniqueString name)

Given a name and a Scope, return the innermost and first ID for a definition of that name, and an indication of whether 0, 1, or more matches were found.

const std::vector<ID> findUsedImportedModules(Context *context, const Scope *scope)

Given a scope, returns a list of IDs for all the modules that were either used or imported in that scope. May return an empty vector if no modules were used or imported in the scope.

const ResolvedVisibilityScope *resolveVisibilityStmts(Context *context, const Scope *scope)

Resolve the uses and imports in a given scope.

const Scope *scopeForAutoModule(Context *context)

Return the scope for the automatically included ‘ChapelStandard’ module, or nullptr if it could not be found.

const std::vector<std::pair<ID, ID>> &moduleInitializationOrder(Context *context, ID entrypoint)

Given the ID for a module ‘entrypoint’, compute the order in which modules should be initialized. Note that this ordering does not consider liveliness, and modules that are never used or have no module level statements will currently still be listed in the result.

The result is list of ID pairs. The first ID in a pair is the module to be initialized, and the second ID is the module that first triggered initialization. The second ID may be empty if the first ID is the entrypoint module or if initialization was triggered implicitly.

void emitMultipleDefinedSymbolErrors(Context *context, const Scope *scope)

Check for symbol names with multiple definitions within a scope. This query only exists to emit errors.

std::set<ID> computeSplitInits(Context *context, const uast::AstNode *symbol, const ResolutionResultByPostorderID &byPostorder)
class ApplicabilityResult
#include <resolution-types.h>

Represents either a function that was accepted during call resolution, or the reason why that function was rejected.

Public Functions

inline ApplicabilityResult()
inline bool operator==(const ApplicabilityResult &other) const
inline bool operator!=(const ApplicabilityResult &other) const
inline void mark(Context *context) const
inline size_t hash() const
inline const ID &idForErr() const
inline const TypedFnSignature *initialForErr() const
inline const TypedFnSignature *candidate() const
inline bool success() const
inline CandidateFailureReason reason() const
inline PassingFailureReason formalReason() const
inline int formalIdx() const

Public Static Functions

static inline ApplicabilityResult success(const TypedFnSignature *candidate)
static inline ApplicabilityResult failure(const TypedFnSignature *initialForErr, PassingFailureReason reason, int formalIdx)
static inline ApplicabilityResult failure(ID idForErr, CandidateFailureReason reason)
static inline bool update(ApplicabilityResult &keep, ApplicabilityResult &addin)
class AssociatedAction
#include <resolution-types.h>

This type represents an associated action (for use within a ResolvedExpression).

Public Types

enum Action

Values:

enumerator ASSIGN
enumerator COPY_INIT
enumerator INIT_OTHER
enumerator DEFAULT_INIT
enumerator DEINIT
enumerator ITERATE
enumerator NEW_INIT
enumerator REDUCE_SCAN
enumerator INFER_TYPE
enumerator COMPARE

Public Functions

inline AssociatedAction(Action action, const TypedFnSignature *fn, ID id)
inline bool operator==(const AssociatedAction &other) const
inline bool operator!=(const AssociatedAction &other) const
inline Action action() const

Returns which action this represents

inline const TypedFnSignature *fn() const

Return which function is called to help with the action

inline const ID &id() const

Return the ID is associated with the action

inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static const char *kindToString(Action a)
class BorrowedIdsWithName
#include <scope-types.h>

Contains IDs with a particular name. This class is a lightweight reference to a collection stored in OwnedIdsWithName.

Public Functions

inline int numIds() const

Return the number of IDs stored here

inline const ID &firstId() const

Returns the first ID in this list.

inline const IdAndFlags &firstIdAndFlags() const

Returns the first IdAndFlags in this list.

bool containsOnlyMethodsOrFields() const

Returns ‘true’ if the list contains only IDs that represent methods or fields.

inline BorrowedIdsWithNameIter begin() const
inline BorrowedIdsWithNameIter end() const
inline bool operator==(const BorrowedIdsWithName &other) const
inline bool operator!=(const BorrowedIdsWithName &other) const
inline size_t hash() const
inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline optional<BorrowedIdsWithName> createWithSingleId(ID id, uast::Decl::Visibility vis, bool isField, bool isMethod, bool isParenfulFunction, IdAndFlags::Flags filterFlags, IdAndFlags::FlagSet excludeFlagSet)
static inline BorrowedIdsWithName createWithToplevelModuleId(ID id)
static inline BorrowedIdsWithName createWithBuiltinId()
class BorrowedIdsWithNameIter
#include <scope-types.h>

Iterator that skips invisible entries from the list of borrowed IDs.

Public Types

using difference_type = std::ptrdiff_t
using value_type = ID
using pointer = const ID*
using reference = const ID&
using iterator_category = std::forward_iterator_tag

Public Functions

inline bool operator!=(const BorrowedIdsWithNameIter &other) const
inline BorrowedIdsWithNameIter &operator++()
inline const ID &operator*() const
inline const IdAndFlags &curIdAndFlags() const
class CallInfo
#include <resolution-types.h>

CallInfo

Public Types

using CallInfoActualIterable = Iterable<std::vector<CallInfoActual>>

Public Functions

inline CallInfo(UniqueString name, types::QualifiedType calledType, bool isMethodCall, bool hasQuestionArg, bool isParenless, std::vector<CallInfoActual> actuals)

Construct a CallInfo that contains QualifiedTypes for actuals

inline const UniqueString name() const

return the name of the called thing

inline types::QualifiedType calledType() const

return the type of the called thing

inline bool isMethodCall() const

check if the call is a method call

inline bool isOpCall() const

check if the call is an operator call

inline bool hasQuestionArg() const

check if the call includes ? arg for type constructor

inline bool isParenless() const

return true if the call did not use parens

inline CallInfoActualIterable actuals() const

return the actuals

inline const CallInfoActual &actual(size_t i) const

return the i’th actual

inline size_t numActuals() const

return the number of actuals

inline bool operator==(const CallInfo &other) const
inline bool operator!=(const CallInfo &other) const
inline void mark(Context *context) const
inline size_t hash() const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static CallInfo createSimple(const uast::FnCall *call)

Construct a CallInfo with unknown types for the actuals that can be used for FormalActualMap but not much else. Assumes that the calledExpression is an identifier and that it is a function name (vs a method invocation).

static CallInfo create(Context *context, const uast::Call *call, const ResolutionResultByPostorderID &byPostorder, bool raiseErrors = true, std::vector<const uast::AstNode*> *actualAsts = nullptr, UniqueString rename = UniqueString())

Construct a CallInfo from a Call and optionally raise errors that occur when doing so. Assumes that the actual arguments have already been resolved and their types are available in ‘byPostorder’.

If ‘raiseErrors’ is ‘true’ (the default), then errors encountered will be raised on the current query.

If actualAsts is provided and not ‘nullptr’, it will be updated to contain the uAST pointers for each actual.

static CallInfo createWithReceiver(const CallInfo &ci, types::QualifiedType receiverType, UniqueString rename = UniqueString())

Construct a CallInfo by adding a method receiver argument to the passed CallInfo.

static CallInfo copyAndRename(const CallInfo &ci, UniqueString rename)

Copy and rename a CallInfo.

static void prepareActuals(Context *context, const uast::Call *call, const ResolutionResultByPostorderID &byPostorder, bool raiseErrors, std::vector<CallInfoActual> &actuals, const uast::AstNode *&questionArg, std::vector<const uast::AstNode*> *actualAsts)

Prepare actuals for a call for later use in creating a CallInfo. This is a helper function for CallInfo::create that is sometimes useful to call separately.

Sets ‘actuals’ and ‘hasQuestionArg’.

If actualIds is not ‘nullptr’, then the toID value of each actual is pushed to that array.

class CallInfoActual
#include <resolution-types.h>

CallInfoActual

Public Functions

inline CallInfoActual(types::QualifiedType type, UniqueString byName)
inline const types::QualifiedType &type() const

return the qualified type

inline UniqueString byName() const

return the name, if any, that the argument was passed with. Ex: in f(number=3), byName() would be “number”

inline bool operator==(const CallInfoActual &other) const
inline bool operator!=(const CallInfoActual &other) const
inline void mark(Context *context) const
inline size_t hash() const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const
class CallResolutionResult
#include <resolution-types.h>

CallResolutionResult

Public Functions

inline CallResolutionResult()
inline CallResolutionResult(types::QualifiedType exprType)
inline CallResolutionResult(MostSpecificCandidates mostSpecific, types::QualifiedType exprType, PoiInfo poiInfo, bool speciallyHandled = false)
inline const MostSpecificCandidates &mostSpecific() const

get the most specific candidates for return-intent overloading

inline const types::QualifiedType &exprType() const

type of the call expression

inline const PoiInfo &poiInfo() const

point-of-instantiation scopes used when resolving signature or body

inline bool speciallyHandled() const

whether the resolution result was handled using some compiler-level logic

inline bool operator==(const CallResolutionResult &other) const
inline bool operator!=(const CallResolutionResult &other) const
inline void swap(CallResolutionResult &other)
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const
struct CandidatesAndForwardingInfo

Public Types

using const_iterator = std::vector<const TypedFnSignature*>::const_iterator

Public Functions

inline void addCandidate(const TypedFnSignature *candidate)
inline void helpComputeForwardingTo(const CallInfo &fci, size_t start)
inline void takeFromOther(CandidatesAndForwardingInfo &other)
inline const TypedFnSignature *get(size_t i) const
inline const types::QualifiedType &getForwardingInfo(size_t i) const
inline bool empty() const
inline size_t size() const
inline bool hasForwardingInfo() const
inline const_iterator begin() const
inline const_iterator end() const
inline size_t hash() const
inline void mark(Context *context) const
inline bool operator==(const CandidatesAndForwardingInfo &other) const
inline void swap(CandidatesAndForwardingInfo &other)
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline bool update(CandidatesAndForwardingInfo &keep, CandidatesAndForwardingInfo &addin)
class CanPassResult

Public Types

enum ConversionKind

Values:

enumerator NONE

No implicit conversion is needed

enumerator PARAM_NARROWING

A narrowing param conversion is needed. These are only applicable to the particular param value &#8212; e.g. 1:int converting to int(8) because 1 fits in int(8). The input of such a conversion must be param and the result is always a param.

enumerator NUMERIC

A numeric or bool conversion.

enumerator SUBTYPE

A conversion that implements subtyping

enumerator BORROWS

A conversion that borrows a managed type (without subtyping)

enumerator BORROWS_SUBTYPE

A conversion that implements subtyping AND borrows a managed type

enumerator OTHER

Non-subtype conversion that doesn’t produce a param

Public Functions

inline CanPassResult()
~CanPassResult() = default
inline bool passes() const

Returns true if the argument is passable

inline PassingFailureReason reason() const
inline bool instantiates() const

Returns true if passing the argument will require instantiation

inline bool promotes() const

Returns true if passing the argument will require promotion

inline bool converts() const

Returns true if implicit conversion is required

inline ConversionKind conversionKind() const

What type of implicit conversion, if any, is needed?

inline bool convertsWithParamNarrowing() const

Returns true if an implicit param narrowing conversion is required

inline bool convertsWithBorrowing() const

Returns true if an implicit borrowing conversion is required. Does not include borrowing with implicit subtyping.

Public Static Functions

static CanPassResult canPass(Context *context, const types::QualifiedType &actualType, const types::QualifiedType &formalType)
struct CheckedScope
#include <scope-types.h>

The type to help maintain a checked scope

Public Functions

inline CheckedScope(UniqueString forName, const Scope *scope)
inline bool operator==(const CheckedScope &other) const
inline bool operator!=(const CheckedScope &other) const
inline size_t hash() const

Public Members

UniqueString forName
const Scope *scope = nullptr
struct CopyableAssignableInfo

Public Functions

inline CopyableAssignableInfo()
inline bool isFromConst() const
inline bool isFromRef() const
inline void intersectWith(const CopyableAssignableInfo &other)
inline bool operator==(const CopyableAssignableInfo &other) const
inline bool operator!=(const CopyableAssignableInfo &other) const
inline void swap(CopyableAssignableInfo &other)
inline void mark(Context *context) const

Public Static Functions

static inline CopyableAssignableInfo fromConst()
static inline CopyableAssignableInfo fromRef()
static inline CopyableAssignableInfo fromNone()
static inline bool update(CopyableAssignableInfo &keep, CopyableAssignableInfo &addin)
class FormalActual
#include <resolution-types.h>

FormalActual holds information on a function formal and its binding (if any)

Public Functions

inline bool operator==(const FormalActual &other) const
inline bool operator!=(const FormalActual &other) const
inline void mark(Context *context) const
inline size_t hash() const
inline const types::QualifiedType &formalType() const
inline const types::QualifiedType &actualType() const
inline const uast::Decl *formal() const
inline int formalIdx() const
inline int actualIdx() const
inline bool hasActual() const
inline bool formalInstantiated() const
inline bool hasDefault() const
inline bool isVarArgEntry() const
class FormalActualMap
#include <resolution-types.h>

FormalActualMap maps formals to actuals

Public Types

using FormalActualIterable = Iterable<std::vector<FormalActual>>

Public Functions

inline FormalActualMap(const UntypedFnSignature *sig, const CallInfo &call)
inline FormalActualMap(const TypedFnSignature *sig, const CallInfo &call)
inline bool operator==(const FormalActualMap &other) const
inline bool operator!=(const FormalActualMap &other) const
inline void mark(Context *context) const
inline size_t hash() const
inline bool isValid() const

check if mapping is valid

inline FormalActualIterable byFormals() const

get the FormalActuals in the order of the formal arguments

inline const FormalActual &byFormalIdx(int formalIdx) const

get the FormalActual for a particular formal index

inline const FormalActual *byActualIdx(int actualIdx) const

get the FormalActual for a particular actual index, and returns nullptr if none was found.

class IdAndFlags
#include <scope-types.h>

Helper type to store an ID and visibility constraints.

Public Types

using Flags = uint16_t

A bit-set of the flags defined in the above enum. Represents a conjunction / AND of all the set bit. E.g.: just IdAndFlags::PUBLIC &#8212; only public symbols just IdAndFlags::METHOD_FIELD &#8212; only methods/fields IdAndFlags::PUBLIC | IdAndFlags::METHOD_FIELD &#8212; only public symbols that are methods/fields Empty Flags &#8212; match everything

Public Functions

inline IdAndFlags(ID id, uast::Decl::Visibility vis, bool isField, bool isMethod, bool isParenfulFunction)
inline bool operator==(const IdAndFlags &other) const
inline bool operator!=(const IdAndFlags &other) const
inline size_t hash() const
inline void mark(Context *context) const
inline const ID &id() const
inline bool isPublic() const
inline bool isMethodOrField() const
inline bool isMethod() const
inline bool isParenfulFunction() const

Public Static Functions

static inline bool matchFilter(Flags haveFlags, Flags filterFlags, const FlagSet &excludeFlagSet)
static std::string flagsToString(Flags flags)
class FlagSet
#include <scope-types.h>

A set of bit-sets / flag combinations. Logically, while Flags represents a conjunction of all of its bitfields (see documentation on Flags), this FlagSet represents a disjunction of each flag combination. That is to say, if FlagSet contains:

IdAndFlags::PUBLIC, IdAndFlags::NOT_PUBLIC | IdAndFlags::METHOD_FIELD
This represents the following condition on variables:
IdAndFlags::PUBLIC ∨ (IdAndFlags::NOT_PUBLIC ∧ IdAndFlags::METHOD_FIELD)
That is, either any public symbol, or a private method or field.

Other examples: [] (empty FlagSet) &#8212; matches nothing. [IdAndFlags::PUBLIC | IdAndFlags::METHOD_FIELD] &#8212; only public symbols that are methods / fields. More generally, [f] (singleton set) &#8212; equivalent to the single contained Flags value f.

Inserting into the FlagSet automatically tries to perform basic simplification to avoid growing the size.

Public Functions

FlagSet() = default
FlagSet(const FlagSet &other) = default
FlagSet(FlagSet &&other) = default
FlagSet &operator=(const FlagSet &other) = default
FlagSet &operator=(FlagSet &&other) = default
void addDisjunction(Flags excludeFlags)

Add a new disjunct to the set of flag combinations. Automatically performs some deduplication and packing to avoid growing the set if possible.

bool subsumes(Flags mightBeSubsumed) const
bool noneMatch(Flags match) const

Checks that none of the or’ed flag combinations match the given flags.

bool operator==(const FlagSet &other) const
bool operator!=(const FlagSet &other) const
size_t hash() const
void mark(Context *context) const

Public Static Functions

static FlagSet singleton(Flags flags)

Create a FlagSet consisting of only one combination of Flags. Flags represents a conjunction (AND) of properties; see the comment on Flags for more info.

static FlagSet empty()

Create a FlagSet consisting of no flag combinations; such a set matches nothing (the base case of OR is false).

class InnermostMatch
#include <scope-types.h>

InnermostMatch

Public Types

enum MatchesFound

Values:

enumerator ZERO
enumerator ONE
enumerator MANY

Public Functions

inline InnermostMatch()
inline InnermostMatch(ID id, MatchesFound found)
inline ID id() const

Return the id

inline MatchesFound found() const

Return the matches found

inline bool operator==(const InnermostMatch &other) const
inline bool operator!=(const InnermostMatch &other) const
inline void swap(InnermostMatch &other)
inline void mark(Context *context) const
inline void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline bool update(InnermostMatch &keep, InnermostMatch &addin)
class KindProperties

Public Functions

void setRef(bool isRef)
void setParam(bool isParam)
void combineWith(const KindProperties &other)
void strictCombineWith(const KindProperties &other)
types::QualifiedType::Kind toKind() const
inline bool valid() const

Public Static Functions

static KindProperties fromKind(types::QualifiedType::Kind kind)
class MostSpecificCandidate
#include <resolution-types.h>

Stores a function candidate. This information includes both the TypedFnSignature* representing the candidate, as well as information about this candidate’s applicability. In particular, we store whether or not this candidate requires a const ref coercion, which is allowed by the spec, but is not allowed in practice due to the aliasing rules of C.

Public Functions

inline MostSpecificCandidate()
MostSpecificCandidate &operator=(MostSpecificCandidate &&other) = default
inline MostSpecificCandidate &operator=(const MostSpecificCandidate &other)
MostSpecificCandidate(MostSpecificCandidate &&other) = default
inline MostSpecificCandidate(const MostSpecificCandidate &other)
inline const TypedFnSignature *fn() const
inline const FormalActualMap &formalActualMap() const
inline int constRefCoercionFormal() const
inline int constRefCoercionActual() const
inline bool hasConstRefCoercion() const
inline operator bool() const
inline bool operator==(const MostSpecificCandidate &other) const
inline bool operator!=(const MostSpecificCandidate &other) const
inline void mark(Context *context) const
inline size_t hash() const
inline void swap(MostSpecificCandidate &other)
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static MostSpecificCandidate fromTypedFnSignature(Context *context, const TypedFnSignature *fn, const FormalActualMap &faMap)
static MostSpecificCandidate fromTypedFnSignature(Context *context, const TypedFnSignature *fn, const CallInfo &info)
static inline bool update(MostSpecificCandidate &keep, MostSpecificCandidate &addin)
class MostSpecificCandidates
#include <resolution-types.h>

Stores the most specific candidates when resolving a function call.

Public Types

enum Intent

Values:

enumerator ONLY
enumerator REF
enumerator CONST_REF
enumerator VALUE
enumerator NUM_INTENTS

Public Functions

inline MostSpecificCandidates()

Default-initialize MostSpecificCandidates with no candidates which is not empty due to ambiguity.

void inferOutFormals(Context *context, const PoiScope *instantiationPoiScope)

Adjust each candidate signature by inferring generic ‘out’ intent formals if there are any.

inline MostSpecificCandidate const *begin() const
inline MostSpecificCandidate const *end() const
inline void setBestRef(MostSpecificCandidate c)
inline void setBestConstRef(MostSpecificCandidate c)
inline void setBestValue(MostSpecificCandidate c)
inline void setBestOnly(MostSpecificCandidate c)
inline const MostSpecificCandidate &bestRef() const
inline const MostSpecificCandidate &bestConstRef() const
inline const MostSpecificCandidate &bestValue() const
inline const MostSpecificCandidate &only() const

If there is exactly one candidate, return that candidate. Otherwise, return an empty candidate.

inline int numBest() const

Returns the number of best candidates that are contained here.

inline bool isEmpty() const

Returns true if there are no most specific candidates.

inline bool isAmbiguous() const

Returns true if there are no most specific candidates due to ambiguity.

inline bool foundCandidates() const

Returns ‘true’ if any candidate was found, including if there was no best candidate due to ambiguity.

inline bool operator==(const MostSpecificCandidates &other) const
inline bool operator!=(const MostSpecificCandidates &other) const
inline void swap(MostSpecificCandidates &other)
inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline MostSpecificCandidates getOnly(MostSpecificCandidate c)

If fn is not nullptr, creates a MostSpecificCandidates with that function. Otherwise, default-initializes a MostSpecificCandidates with no candidates that is not empty due to ambiguity.

static inline MostSpecificCandidates getEmpty()

Creates a MostSpecificCandidates with no candidates that is not empty due to ambiguity.

static inline MostSpecificCandidates getAmbiguous()

Creates a MostSpecificCandidates that represents a no candidates but that is empty due to ambiguity.

static inline bool update(MostSpecificCandidates &keep, MostSpecificCandidates &addin)
template<typename UV>
class MutatingResolvedVisitor
#include <ResolvedVisitor.h>

Similar to ResolvedVisitor but this one works with a mutable ResolutionResultByPostorderID.

Public Functions

inline MutatingResolvedVisitor(Context *context, const uast::AstNode *ast, UV &userVisitor, const ResolutionResultByPostorderID &byPostorder)
inline Context *context() const

Return the context used by this ResolvedVisitor

inline const uast::AstNode *ast() const

Return the uAST node being visited by this ResolvedVisitor

inline UV &userVisitor()

Return the user visitor that this ResolvedVisitor invokes

inline const UV &userVisitor() const

Return the user visitor that this ResolvedVisitor invokes

inline ResolutionResultByPostorderID &byPostorder() const

Return the current ResolutionResultByPostorderID which can be used to gather type information

inline bool hasAst(const uast::AstNode *ast) const

Returns if the ResolutionResultByPostorderID has a result for a particular uAST node

inline ResolvedExpression &byAst(const uast::AstNode *ast) const

Return the ResolvedExpression for a particular uAST node

inline bool hasId(const ID &id) const

Returns if the ResolutionResultByPostorderID has a result for a particular ID

inline ResolvedExpression &byId(const ID &id) const

Return the ResolvedExpression for a particular ID

inline bool enter(const uast::For *loop)
inline void exit(const uast::For *loop)
inline bool enter(const uast::AstNode *ast)
inline void exit(const uast::AstNode *ast)
class OuterVariables
#include <resolution-types.h>

This type represents the outer variables used in a function. It stores the variables and all their mentions in lexical order. It presents the concept of a ‘reaching variable’, which is a reference to an outer variable that is not defined in the symbol’s immediate parent.

Public Functions

inline OuterVariables(Context *context, ID symbol)
~OuterVariables() = default
inline bool operator==(const OuterVariables &other) const
inline bool operator!=(const OuterVariables &other) const
inline void swap(OuterVariables &other)
inline void mark(Context *context) const
void add(Context *context, ID mention, ID var)
inline bool isEmpty() const

Returns ‘true’ if there are no outer variables.

inline int numVariables() const

The total number of outer variables.

inline int numImmediateVariables() const

The number of outer variables declared in our immediate parent.

inline int numReachingVariables() const

The number of outer variables declared in our non-immediate parents.

inline int numMentions() const

The number of outer variable mentions in this symbol’s body.

inline int numMentions(const ID &var) const

Get the number of mentions for ‘var’ in this symbol.

inline bool mentions(const ID &var) const

Returns ‘true’ if there is at least one mention of ‘var’.

inline bool contains(const ID &var) const

Returns ‘true’ if this contains an entry for ‘var’.

inline ID variable(size_t idx) const

Get the i’th outer variable or the empty ID if ‘idx’ was out of bounds.

inline bool isReachingVariable(const ID &var) const

A reaching variable is declared in a non-immediate parent(s).

inline bool isReachingVariable(size_t idx) const

A reaching variable is declared in a non-immediate parent(s).

inline ID mention(size_t idx) const

Get the i’th mention in this function.

inline ID mention(const ID &var, size_t idx) const

Get the i’th mention for ‘var’ within this function, or the empty ID.

inline ID firstMention(const ID &var) const

Get the first mention of ‘var’, or the empty ID.

inline const ID &symbol() const

Get the ID of the symbol this instance was created for.

inline const ID &parent() const

Get the ID of the owning symbol’s parent.

Public Static Functions

static inline bool update(owned<OuterVariables> &keep, owned<OuterVariables> &addin)
class OwnedIdsWithName
#include <scope-types.h>

Collects IDs with a particular name. These can be referred to by a BorrowedIdsWithName in a way that avoids copies.

Public Functions

inline OwnedIdsWithName(ID id, uast::Decl::Visibility vis, bool isField, bool isMethod, bool isParenfulFunction)

Construct an OwnedIdsWithName containing one ID.

inline void appendIdAndFlags(ID id, uast::Decl::Visibility vis, bool isField, bool isMethod, bool isParenfulFunction)

Append an ID to an OwnedIdsWithName.

inline int numIds() const
inline bool operator==(const OwnedIdsWithName &other) const
inline bool operator!=(const OwnedIdsWithName &other) const
inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const
optional<BorrowedIdsWithName> borrow(IdAndFlags::Flags filterFlags, const IdAndFlags::FlagSet &excludeFlagSet) const
class PoiInfo
#include <resolution-types.h>

Contains information about symbols available from point-of-instantiation in order to implement caching of instantiations.

Public Functions

inline PoiInfo()
inline PoiInfo(const PoiScope *poiScope)
inline PoiInfo(std::set<std::pair<ID, ID>> poiFnIdsUsed)
inline const PoiScope *poiScope() const

return the poiScope

inline void setPoiScope(const PoiScope *poiScope)

set the poiScope

inline void setResolved(bool resolved)

set resolved

inline const PoiCallIdFnIds &poiFnIdsUsed() const
inline const PoiRecursiveCalls &recursiveFnsUsed() const
inline void addIds(ID a, ID b)
inline void swap(PoiInfo &other)
void accumulate(const PoiInfo &addPoiInfo)
void accumulateRecursive(const TypedFnSignature *signature, const PoiScope *poiScope)
bool canReuse(const PoiInfo &check) const
inline size_t hash() const
inline bool operator==(const PoiInfo &other) const
inline bool operator!=(const PoiInfo &other) const
inline void mark(Context *context) const
inline void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline bool updateEquals(const PoiInfo &a, const PoiInfo &b)
static inline bool reuseEquals(const PoiInfo &a, const PoiInfo &b)
class PoiScope
#include <scope-types.h>

PoiScope is a point-of-instantiation scope

Public Functions

inline PoiScope(const Scope *scope, const PoiScope *poiScope)
inline const Scope *inScope() const

return the parent scope for the call

inline const PoiScope *inFnPoi() const

return the POI of this POI

inline bool operator==(const PoiScope &other) const
inline bool operator!=(const PoiScope &other) const
inline void mark(Context *context) const
inline void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline bool update(owned<PoiScope> &keep, owned<PoiScope> &addin)
class ResolutionResultByPostorderID
#include <resolution-types.h>

This type is a mapping from postOrderId (which is an integer) to ResolvedExpression for storing resolution results within a symbol.

Note that an inner Function would not be covered here.

Public Functions

void setupForSymbol(const uast::AstNode *ast)

prepare to resolve the contents of the passed symbol

void setupForSignature(const uast::Function *func)

prepare to resolve the signature of the passed function

void setupForFunction(const uast::Function *func)

prepare to resolve the body of the passed function

void setupForParamLoop(const uast::For *loop, ResolutionResultByPostorderID &parent)

prepare to resolve the body of a For loop

inline bool hasId(const ID &id) const
inline ResolvedExpression &byId(const ID &id)
inline const ResolvedExpression &byId(const ID &id) const
inline const ResolvedExpression *byIdOrNull(const ID &id) const
inline bool hasAst(const uast::AstNode *ast) const
inline ResolvedExpression &byAst(const uast::AstNode *ast)
inline const ResolvedExpression &byAst(const uast::AstNode *ast) const
inline const ResolvedExpression *byAstOrNull(const uast::AstNode *ast) const
inline bool operator==(const ResolutionResultByPostorderID &other) const
inline bool operator!=(const ResolutionResultByPostorderID &other) const
inline void swap(ResolutionResultByPostorderID &other)
inline void mark(Context *context) const

Public Static Functions

static bool update(ResolutionResultByPostorderID &keep, ResolutionResultByPostorderID &addin)
class ResolvedExpression
#include <resolution-types.h>

This type represents a resolved expression.

Public Types

using AssociatedActions = std::vector<AssociatedAction>

Public Functions

inline ResolvedExpression()
inline const types::QualifiedType &type() const

get the qualified type

inline ID toId() const

for simple (non-function Identifier) cases, the ID of a NamedDecl it refers to

inline bool isBuiltin() const

check whether this resolution result refers to a compiler builtin like bool.

inline const MostSpecificCandidates &mostSpecific() const

For a function call, what is the most specific candidate, or when using return intent overloading, what are the most specific candidates? The choice between these needs to happen later than the main function resolution.

inline const PoiScope *poiScope() const
inline const AssociatedActions &associatedActions() const
inline const ResolvedParamLoop *paramLoop() const
inline void setIsBuiltin(bool isBuiltin)

set the isPrimitive flag

inline void setToId(ID toId)

set the toId

inline void setType(const types::QualifiedType &type)

set the type

inline void setMostSpecific(const MostSpecificCandidates &mostSpecific)

set the most specific

inline void setPoiScope(const PoiScope *poiScope)

set the point-of-instantiation scope

inline void addAssociatedAction(AssociatedAction::Action action, const TypedFnSignature *fn, ID id)

add an associated function

inline void setParamLoop(const ResolvedParamLoop *paramLoop)
inline bool operator==(const ResolvedExpression &other) const
inline bool operator!=(const ResolvedExpression &other) const
inline void swap(ResolvedExpression &other)
inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline bool update(ResolvedExpression &keep, ResolvedExpression &addin)
class ResolvedFields
#include <resolution-types.h>

ResolvedFields represents the fully resolved fields for a class/record/union/tuple type.

It also stores the result of computing the types of ‘forwarding’ statements.

Public Functions

inline ResolvedFields()
inline void setType(const types::CompositeType *type)
inline void addField(UniqueString name, bool hasDefaultValue, ID declId, types::QualifiedType type)
inline void addForwarding(ID forwardingId, types::QualifiedType receiverType)
inline void addForwarding(const ResolvedFields &other)
void finalizeFields(Context *context)
inline bool isGeneric() const

Returns true if this is a generic type

inline bool isGenericWithDefaults() const

Returns true if this is a generic type where all generic fields have default values. For classes, this does not include consideration of the parent class.

inline int numFields() const

Returns the number of fields represented here

inline UniqueString fieldName(int i) const

Returns the field name for the i’th field

inline bool fieldHasDefaultValue(int i) const

Returns ‘true’ if the i’th field has a default value

inline ID fieldDeclId(int i) const

Returns the i’th field’s declaration ID

inline types::QualifiedType fieldType(int i) const

Returns the type of the i’th field

inline int numForwards() const

Returns the number of ‘forwarding’ statements

inline const ID &forwardingStmt(int i) const

Returns the ID of the i’th ‘forwarding’ statement

inline const types::QualifiedType &forwardingToType(int i) const

Returns the type that the i’th ‘forwarding’ statement forwards to

inline bool operator==(const ResolvedFields &other) const
inline bool operator!=(const ResolvedFields &other) const
inline void swap(ResolvedFields &other)
inline void mark(Context *context) const

Public Static Functions

static inline bool update(ResolvedFields &keep, ResolvedFields &addin)
class ResolvedFunction
#include <resolution-types.h>

This type represents a resolved function.

Public Functions

inline ResolvedFunction(const TypedFnSignature *signature, uast::Function::ReturnIntent returnIntent, ResolutionResultByPostorderID resolutionById, PoiInfo poiInfo, types::QualifiedType returnType)
inline const TypedFnSignature *signature() const

The type signature

inline uast::Function::ReturnIntent returnIntent() const

the return intent

inline const types::QualifiedType &returnType() const

the return type

inline const ResolutionResultByPostorderID &resolutionById() const

this is the output of the resolution process

inline const PoiInfo &poiInfo() const

the set of point-of-instantiations used by the instantiation

inline bool operator==(const ResolvedFunction &other) const
inline bool operator!=(const ResolvedFunction &other) const
inline void swap(ResolvedFunction &other)
inline void mark(Context *context) const
inline const ResolvedExpression &byId(const ID &id) const
inline const ResolvedExpression &byAst(const uast::AstNode *ast) const
inline const ResolvedExpression *byAstOrNull(const uast::AstNode *ast) const
inline const ID &id() const

Public Static Functions

static inline bool update(owned<ResolvedFunction> &keep, owned<ResolvedFunction> &addin)
class ResolvedParamLoop

Public Types

using LoopBodies = std::vector<ResolutionResultByPostorderID>

Public Functions

inline ResolvedParamLoop(const uast::For *loop)
inline const uast::For *loop() const
inline const LoopBodies &loopBodies() const
inline void setLoopBodies(const LoopBodies &loopBodies)
inline void mark(Context *context) const
inline bool operator==(const ResolvedParamLoop &other) const
inline bool operator!=(const ResolvedParamLoop &other) const
inline void swap(ResolvedParamLoop &other)

Public Static Functions

static inline bool update(ResolvedParamLoop &keep, ResolvedParamLoop &addin)
class ResolvedVisibilityScope
#include <scope-types.h>

Stores the result of in-order resolution of use/import statements.

Public Types

using VisibilitySymbolsIterable = Iterable<std::vector<VisibilitySymbols>>

Public Functions

inline ResolvedVisibilityScope(const Scope *scope)
inline const Scope *scope() const

Return the scope

inline VisibilitySymbolsIterable visibilityClauses() const

Return an iterator over the visibility clauses

inline void addVisibilityClause(const Scope *scope, VisibilitySymbols::Kind kind, bool isPrivate, bool isModulePrivate, VisibilitySymbols::ShadowScope shadowScopeLevel, ID visibilityClauseId, std::vector<std::pair<UniqueString, UniqueString>> n)

Add a visibility clause

inline bool operator==(const ResolvedVisibilityScope &other) const
inline bool operator!=(const ResolvedVisibilityScope &other) const
inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline bool update(owned<ResolvedVisibilityScope> &keep, owned<ResolvedVisibilityScope> &addin)
template<typename UV>
class ResolvedVisitor
#include <ResolvedVisitor.h>

This class enables visiting resolved uAST nodes. It is a kind of adapter that converts untyped visiting (traversing uAST nodes with a ResolvedVisitor) to typed visiting (traversing uAST nodes with the provided User Visitor (UV)).

The enter/exit calls invoke enter/exit on the User Visitor while passing in a reference to the current ResolvedVisitor. It is possible to get the type of a uAST node from the current ResolvedVisitor.

To use this, create a custom class, and within it, declare enter/exit calls like so:

class MyResolvedVisitor { … bool enter(const AstNode* ast, RV& rv); void exit(const AstNode* ast, RV& rv); … }

Then, use this pattern to visit:

ResolvedVisitor<MyResolvedVisitor> rv(context, symbol,

myResolvedVisitor, byPostorder); symbol->traverse(rv);

Public Functions

inline ResolvedVisitor(Context *context, const uast::AstNode *ast, UV &userVisitor, const ResolutionResultByPostorderID &byPostorder)
inline Context *context() const

Return the context used by this ResolvedVisitor

inline const uast::AstNode *ast() const

Return the uAST node being visited by this ResolvedVisitor

inline UV &userVisitor()

Return the user visitor that this ResolvedVisitor invokes

inline const UV &userVisitor() const

Return the user visitor that this ResolvedVisitor invokes

inline const ResolutionResultByPostorderID &byPostorder() const

Return the current ResolutionResultByPostorderID which can be used to gather type information

inline bool hasAst(const uast::AstNode *ast) const

Returns if the ResolutionResultByPostorderID has a result for a particular uAST node

inline const ResolvedExpression &byAst(const uast::AstNode *ast) const

Return the ResolvedExpression for a particular uAST node

inline bool hasId(const ID &id) const

Returns if the ResolutionResultByPostorderID has a result for a particular ID

inline const ResolvedExpression &byId(const ID &id) const

Return the ResolvedExpression for a particular ID

inline bool enter(const uast::For *loop)
inline void exit(const uast::For *loop)
inline bool enter(const uast::AstNode *ast)
inline void exit(const uast::AstNode *ast)
struct ResultVisibilityTrace
#include <scope-types.h>

ResultVisibilityTrace stores a tracing of the name lookup process which can be useful for error messages.

Public Functions

inline bool operator==(const ResultVisibilityTrace &other) const
inline bool operator!=(const ResultVisibilityTrace &other) const
inline void mark(Context *context) const

Public Members

const Scope *scope = nullptr
std::vector<VisibilityTraceElt> visibleThrough
struct VisibilityTraceElt

Public Functions

inline bool operator==(const VisibilityTraceElt &other) const
inline bool operator!=(const VisibilityTraceElt &other) const
inline void mark(Context *context) const

Public Members

VisibilitySymbols::ShadowScope shadowScope = VisibilitySymbols::REGULAR_SCOPE
const ResolvedVisibilityScope *resolvedVisibilityScope = nullptr
ID visibilityClauseId
VisibilityStmtKind visibilityStmtKind = VIS_USE
UniqueString renameFrom
UniqueString usedImportedThingName
const Scope *usedImportedScope = nullptr
bool fromUseImport = false
const Scope *methodReceiverScope = nullptr
const Scope *parentScope = nullptr
bool automaticModule = false
bool toplevelModule = false
bool externBlock = false
bool rootScope = false
class Scope
#include <scope-types.h>

A scope roughly corresponds to a { } block. Anywhere a new symbol could be defined / is defined is a scope.

The scope contains a mapping from name to ID for symbols defined within. For the root scope, it can also contain empty IDs for builtin types and symbols.

While generic instantiations generate something scope-like, the point-of-instantiation reasoning will need to be handled with a different type.

Public Types

using ScopeFlags = unsigned int

A bit-set of the flags defined in the above enum

Public Functions

inline Scope()

Construct an empty scope. This scope will not yet store any defined symbols.

Scope(const uast::AstNode *ast, const Scope *parentScope, bool autoUsesModules)

Construct a Scope for a particular AST node and with a particular parent.

void addBuiltin(UniqueString name)

Add a builtin type with the provided name. This needs to be called to populate the root scope with builtins.

inline const Scope *parentScope() const

Return the parent scope for this scope.

const Scope *moduleScope() const

Return the module scope containing this scope, or if it is a module scope, this scope.

const Scope *parentModuleScope() const

Return the parent module of the module containing this scope. This is equivalent to:

‘scope->moduleScope()->parentScope()->moduleScope()

inline uast::asttags::AstTag tag() const

Returns the AST tag of the construct that this Scope represents.

inline const ID &id() const

Return the ID of the Block or other AST node construct that this Scope represents. An empty ID indicates that this Scope is the root scope.

inline UniqueString name() const
inline bool containsUseImport() const

Returns ‘true’ if this Scope directly contains use or import statements including the automatic ‘use’ for the standard library.

inline bool containsExternBlock() const

Returns ‘true’ if this Scope directly contains an ‘extern’ block (with C code to supporting interoperability)

inline bool autoUsesModules() const

Returns ‘true’ if the Scope includes the automatic ‘use’ for the standard library.

inline bool isMethodScope() const

Returns ‘true’ if this Scope represents a method’s scope. Methods have special scoping behavior to use other fields/methods without writing ‘this.bla’.

inline bool containsFunctionDecls() const

Returns ‘true’ if this Scope directly contains any Functions

inline int numDeclared() const
bool lookupInScope(UniqueString name, std::vector<BorrowedIdsWithName> &result, IdAndFlags::Flags filterFlags, const IdAndFlags::FlagSet &excludeFlagSet) const

If the scope contains IDs with the provided name, append the relevant BorrowedIdsToName the the vector. Returns true if something was appended.

bool contains(UniqueString name) const

Check to see if the scope contains IDs with the provided name.

std::set<UniqueString> gatherNames() const

Gathers all of the names of symbols declared directly within this scope

void collectNames(std::set<UniqueString> &namesDefined, std::set<UniqueString> &namesDefinedMultiply) const

Collect names that are declared directly within this scope but separately collect names that have multiple definitions.

inline bool operator==(const Scope &other) const
inline bool operator!=(const Scope &other) const
inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const

Public Static Functions

static inline bool update(owned<Scope> &keep, owned<Scope> &addin)
class TypedFnSignature
#include <resolution-types.h>

This represents a typed function signature.

Public Types

enum WhereClauseResult

Values:

enumerator WHERE_NONE
enumerator WHERE_TBD
enumerator WHERE_TRUE
enumerator WHERE_FALSE

Public Functions

inline bool operator==(const TypedFnSignature &other) const
inline bool operator!=(const TypedFnSignature &other) const
inline void mark(Context *context) const
void stringify(std::ostream &ss, chpl::StringifyKind stringKind) const
inline const ID &id() const

Returns the id of the relevant uast node (usually a Function but it can be a Record or Class for compiler-generated functions)

inline const UntypedFnSignature *untyped() const

Returns the UntypedFnSignature

inline bool isCompilerGenerated() const
inline WhereClauseResult whereClauseResult() const

Returns the result of evaluating the where clause

inline bool needsInstantiation() const

Returns if any of the formals are generic or unknown

inline const TypedFnSignature *inferredFrom() const

If this TypedFnSignature represents the result of additional inference, return the most basic TypedFnSignature that was inferred from.

inline const TypedFnSignature *instantiatedFrom() const

Is this TypedFnSignature representing an instantiation? If so, returns the generic TypedFnSignature that was instantiated. Otherwise, returns nullptr.

This function always returns the signature for the fully generic function and never a partial instantiation. That is, the result will either be nullptr or result->instantiatedFrom() will be nullptr.

inline bool formalIsInstantiated(int i) const

Returns ‘true’ if formal argument i was instantiated; that is, it was present in the SubstitutionsMap when instantiating.

inline const Bitmap &formalsInstantiatedBitmap() const
inline const TypedFnSignature