// A(1) as a function reference into an array reference or a structure
// constructor.
template<typename... A>
-void FixMisparsedFunctionReference(const std::variant<A...> &constU) {
+void FixMisparsedFunctionReference(
+ semantics::SemanticsContext &context, const std::variant<A...> &constU) {
// The parse tree is updated in situ when resolving an ambiguous parse.
using uType = std::decay_t<decltype(constU)>;
auto &u{const_cast<uType &>(constU)};
}
} else if (symbol.has<semantics::DerivedTypeDetails>()) {
if constexpr (common::HasMember<parser::StructureConstructor, uType>) {
- CHECK(symbol.scope() != nullptr);
- const semantics::DeclTypeSpec *type{
- symbol.scope()->FindInstantiatedDerivedType(
- semantics::DerivedTypeSpec{symbol})};
- CHECK(type != nullptr);
- u = funcRef.ConvertToStructureConstructor(type->derivedTypeSpec());
+ auto &scope{context.FindScope(name->source)};
+ const semantics::DeclTypeSpec &type{
+ scope.FindOrInstantiateDerivedType(
+ semantics::DerivedTypeSpec{symbol}, context)};
+ u = funcRef.ConvertToStructureConstructor(type.derivedTypeSpec());
} else {
common::die("can't fix misparsed function as structure constructor");
}
// Expression was already checked by ExprChecker
return std::make_optional<Expr<SomeType>>(expr.typedExpr->v);
} else {
- FixMisparsedFunctionReference(expr.u);
+ FixMisparsedFunctionReference(context_, expr.u);
if (!expr.source.empty()) {
// Analyze the expression in a specified source position context for
// better error reporting.
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::Variable &variable) {
- FixMisparsedFunctionReference(variable.u);
+ FixMisparsedFunctionReference(context_, variable.u);
return Analyze(variable.u);
}
}
const DeclTypeSpec &Scope::FindOrInstantiateDerivedType(DerivedTypeSpec &&spec,
- DeclTypeSpec::Category category, SemanticsContext &semanticsContext) {
+ SemanticsContext &semanticsContext, DeclTypeSpec::Category category) {
spec.FoldParameterExpressions(semanticsContext.foldingContext());
if (const DeclTypeSpec * type{FindInstantiatedDerivedType(spec, category)}) {
return *type;
// Returns a matching derived type instance if one exists, otherwise
// creates one
- const DeclTypeSpec &FindOrInstantiateDerivedType(
- DerivedTypeSpec &&, DeclTypeSpec::Category, SemanticsContext &);
+ const DeclTypeSpec &FindOrInstantiateDerivedType(DerivedTypeSpec &&,
+ SemanticsContext &, DeclTypeSpec::Category = DeclTypeSpec::TypeDerived);
// Clones a DerivedType scope into a new derived type instance's scope.
void InstantiateDerivedType(Scope &, SemanticsContext &) const;
}
details.ReplaceType(
scope.FindOrInstantiateDerivedType(std::move(newSpec),
- origType->category(), semanticsContext));
+ semanticsContext, origType->category()));
} else if (origType->AsIntrinsic() != nullptr) {
const DeclTypeSpec &newType{scope.InstantiateIntrinsicType(
*origType, semanticsContext)};