void ModFileWriter::PutDerivedType(const Symbol &typeSymbol) {
auto &details{typeSymbol.get<DerivedTypeDetails>()};
PutAttrs(decls_ << "type", typeSymbol.attrs(), ","s, ""s);
- if (!details.extends().empty()) {
- PutLower(decls_ << ",extends(", details.extends().ToString()) << ')';
+ if (const DerivedTypeSpec * extends{typeSymbol.GetParentTypeSpec()}) {
+ PutLower(decls_ << ",extends(", extends->typeSymbol().name().ToString())
+ << ')';
}
PutLower(decls_ << "::", typeSymbol);
auto &typeScope{*typeSymbol.scope()};
if (const Symbol * extends{ResolveDerivedType(*extendsName)}) {
// Declare the "parent component"; private if the type is
if (OkToAddComponent(*extendsName, extends)) {
- symbol.get<DerivedTypeDetails>().set_extends(extendsName->source);
auto &comp{DeclareEntity<ObjectEntityDetails>(*extendsName, Attrs{})};
comp.attrs().set(Attr::PRIVATE, extends->attrs().test(Attr::PRIVATE));
comp.set(Symbol::Flag::ParentComp);
DeclTypeSpec &type{currScope().MakeDerivedType(*extends)};
type.derivedTypeSpec().set_scope(*extends->scope());
comp.SetType(type);
+ DerivedTypeDetails &details{symbol.get<DerivedTypeDetails>()};
+ details.add_component(comp);
}
}
}
}
}
}
+ currScope().symbol()->get<DerivedTypeDetails>().add_component(symbol);
}
ClearArraySpec();
}
}
std::ostream &operator<<(std::ostream &os, const DerivedTypeDetails &x) {
- if (!x.extends().empty()) {
- os << " extends:" << x.extends().ToString();
- }
- if (x.sequence()) {
+ if (x.sequence_) {
os << " sequence";
}
+ if (!x.components_.empty()) {
+ os << " components:";
+ for (auto name : x.components_) {
+ os << ' ' << name.ToString();
+ }
+ }
return os;
}
}
const Symbol *Symbol::GetParentComponent(const Scope *scope) const {
- const auto &details{get<DerivedTypeDetails>()};
if (scope == nullptr) {
CHECK(scope_ != nullptr);
scope = scope_;
}
- if (details.extends().empty()) {
- return nullptr;
- }
- auto iter{scope->find(details.extends())};
- CHECK(iter != scope->end());
- const Symbol &parentComp{*iter->second};
- CHECK(parentComp.test(Symbol::Flag::ParentComp));
- return &parentComp;
+ return get<DerivedTypeDetails>().GetParentComponent(*scope);
}
const DerivedTypeSpec *Symbol::GetParentTypeSpec(const Scope *scope) const {
}
}
+void DerivedTypeDetails::add_component(const Symbol &symbol) {
+ if (symbol.test(Symbol::Flag::ParentComp)) {
+ CHECK(components_.empty());
+ }
+ components_.push_back(symbol.name());
+}
+
std::list<SourceName> DerivedTypeDetails::OrderParameterNames(
const Symbol &type) const {
std::list<SourceName> result;
return result;
}
-std::list<const Symbol *> DerivedTypeDetails::OrderParameterDeclarations(
+SymbolList DerivedTypeDetails::OrderParameterDeclarations(
const Symbol &type) const {
- std::list<const Symbol *> result;
+ SymbolList result;
if (const DerivedTypeSpec * spec{type.GetParentTypeSpec()}) {
const DerivedTypeDetails &details{
spec->typeSymbol().get<DerivedTypeDetails>()};
return result;
}
+SymbolList DerivedTypeDetails::OrderComponents(const Scope &scope) const {
+ SymbolList result;
+ for (SourceName name : components_) {
+ auto iter{scope.find(name)};
+ if (iter != scope.cend()) {
+ const Symbol &symbol{*iter->second};
+ if (symbol.test(Symbol::Flag::ParentComp)) {
+ CHECK(result.empty());
+ const Symbol &typeSymbol{symbol.get<ObjectEntityDetails>()
+ .type()
+ ->AsDerived()
+ ->typeSymbol()};
+ result = typeSymbol.get<DerivedTypeDetails>().OrderComponents(
+ *typeSymbol.scope());
+ }
+ result.push_back(&symbol);
+ }
+ }
+ return result;
+}
+
+const Symbol *DerivedTypeDetails::GetParentComponent(const Scope &scope) const {
+ if (!components_.empty()) {
+ SourceName extends{components_.front()};
+ auto iter{scope.find(extends)};
+ if (iter != scope.cend()) {
+ const Symbol &symbol{*iter->second};
+ if (symbol.test(Symbol::Flag::ParentComp)) {
+ return &symbol;
+ }
+ }
+ }
+ return nullptr;
+}
+
void TypeParamDetails::set_type(const DeclTypeSpec &type) {
CHECK(type_ == nullptr);
type_ = &type;
friend std::ostream &operator<<(std::ostream &, const ProcEntityDetails &);
};
+// These derived type details represent the characteristics of a derived
+// type definition that are shared by all instantiations of that type.
+// The DerivedTypeSpec instances whose type symbols share these details
+// each own a scope into which the components' symbols have been cloned
+// and specialized for each distinct set of type parameter values.
class DerivedTypeDetails {
public:
const std::list<SourceName> ¶mNames() const { return paramNames_; }
- const std::list<const Symbol *> ¶mDecls() const { return paramDecls_; }
- SourceName extends() const { return extends_; }
+ const SymbolList ¶mDecls() const { return paramDecls_; }
bool sequence() const { return sequence_; }
- void add_paramName(const SourceName &name) { paramNames_.emplace_back(name); }
- void add_paramDecl(const Symbol &symbol) {
- paramDecls_.emplace_back(&symbol);
- }
- void set_extends(const SourceName &name) { extends_ = name; }
+ void add_paramName(const SourceName &name) { paramNames_.push_back(name); }
+ void add_paramDecl(const Symbol &symbol) { paramDecls_.push_back(&symbol); }
+ void add_component(const Symbol &);
void set_sequence(bool x = true) { sequence_ = x; }
// Returns the complete list of derived type parameter names in the
// Returns the complete list of derived type parameter symbols in
// the order in which their declarations appear in the derived type
// definitions (parents first).
- std::list<const Symbol *> OrderParameterDeclarations(const Symbol &) const;
+ SymbolList OrderParameterDeclarations(const Symbol &) const;
+
+ // Returns the complete list of derived type components in the order
+ // in which their declarations appear in the derived type definitions
+ // (parents first). Parent components appear in the list immediately
+ // after the components that belong to them.
+ SymbolList OrderComponents(const Scope &) const;
+
+ const Symbol *GetParentComponent(const Scope &) const;
private:
// These are (1) the names of the derived type parameters in the order
// symbols that correspond to those names in the order in which their
// declarations appear in the derived type definition(s).
std::list<SourceName> paramNames_;
- std::list<const Symbol *> paramDecls_;
- // These are the declarations of the derived type's components in component
+ SymbolList paramDecls_;
+ // These are the names of the derived type's components in component
// order. A parent component, if any, appears first in this list.
- std::list<const Symbol *> components_;
- SourceName extends_;
+ std::list<SourceName> components_;
bool sequence_{false};
+ friend std::ostream &operator<<(std::ostream &, const DerivedTypeDetails &);
};
class ProcBindingDetails {