diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -665,6 +665,11 @@ // for a parameterized derived type instantiation with the instance's scope. const DerivedTypeSpec *GetParentTypeSpec(const Scope * = nullptr) const; + // If a derived type's symbol refers to an extended derived type, + // return the parent component's symbol. The scope of the derived type + // can be overridden. + const Symbol *GetParentComponent(const Scope * = nullptr) const; + SemanticsContext &GetSemanticsContext() const; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void dump() const; @@ -686,11 +691,6 @@ friend llvm::raw_ostream &DumpForUnparse( llvm::raw_ostream &, const Symbol &, bool); - // If a derived type's symbol refers to an extended derived type, - // return the parent component's symbol. The scope of the derived type - // can be overridden. - const Symbol *GetParentComponent(const Scope * = nullptr) const; - template friend class Symbols; template friend class std::array; }; diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -987,11 +987,20 @@ if (&component.owner() == &scope) { return Component{std::move(base), component}; } - if (const semantics::Scope * parentScope{scope.GetDerivedTypeParent()}) { - if (const Symbol * parentComponent{parentScope->GetSymbol()}) { - return CreateComponent( - DataRef{Component{std::move(base), *parentComponent}}, component, - *parentScope); + if (const Symbol * typeSymbol{scope.GetSymbol()}) { + if (const Symbol * + parentComponent{typeSymbol->GetParentComponent(&scope)}) { + if (const auto *object{ + parentComponent->detailsIf()}) { + if (const auto *parentType{object->type()}) { + if (const semantics::Scope * + parentScope{parentType->derivedTypeSpec().scope()}) { + return CreateComponent( + DataRef{Component{std::move(base), *parentComponent}}, + component, *parentScope); + } + } + } } } return std::nullopt;