[flang] Eliminate DerivedTypeDetails::extends_ since it is front of component list
authorpeter klausler <pklausler@nvidia.com>
Tue, 5 Feb 2019 18:48:26 +0000 (10:48 -0800)
committerpeter klausler <pklausler@nvidia.com>
Fri, 15 Feb 2019 20:22:03 +0000 (12:22 -0800)
Original-commit: flang-compiler/f18@15150225f83545c76cdb02c83e7be4843d388f94
Reviewed-on: https://github.com/flang-compiler/f18/pull/287
Tree-same-pre-rewrite: false

flang/lib/semantics/mod-file.cc
flang/lib/semantics/resolve-names.cc
flang/lib/semantics/symbol.cc
flang/lib/semantics/symbol.h

index 1e32f93..e79e785 100644 (file)
@@ -195,8 +195,9 @@ void ModFileWriter::PutSymbol(
 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()};
index 3f2ec42..8a282ea 100644 (file)
@@ -2827,13 +2827,14 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
     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);
       }
     }
   }
@@ -2894,6 +2895,7 @@ void DeclarationVisitor::Post(const parser::ComponentDecl &x) {
         }
       }
     }
+    currScope().symbol()->get<DerivedTypeDetails>().add_component(symbol);
   }
   ClearArraySpec();
 }
index a38c039..b57ef3e 100644 (file)
@@ -292,12 +292,15 @@ std::ostream &operator<<(std::ostream &os, const ProcEntityDetails &x) {
 }
 
 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;
 }
 
@@ -576,19 +579,11 @@ Symbol &Symbol::Instantiate(
 }
 
 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 {
@@ -602,6 +597,13 @@ 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;
@@ -616,9 +618,9 @@ std::list<SourceName> DerivedTypeDetails::OrderParameterNames(
   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>()};
@@ -630,6 +632,41 @@ std::list<const Symbol *> DerivedTypeDetails::OrderParameterDeclarations(
   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;
index 0623134..9a96518 100644 (file)
@@ -191,17 +191,19 @@ private:
   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> &paramNames() const { return paramNames_; }
-  const std::list<const Symbol *> &paramDecls() const { return paramDecls_; }
-  SourceName extends() const { return extends_; }
+  const SymbolList &paramDecls() 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
@@ -211,7 +213,15 @@ public:
   // 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
@@ -219,12 +229,12 @@ private:
   // 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 {