@@ -357,6 +357,7 @@ class DeclTypeSpecVisitor : public AttrsVisitor {
357357 DeclTypeSpec::Category category{DeclTypeSpec::TypeDerived};
358358 } derived;
359359 bool allowForwardReferenceToDerivedType{false };
360+ const parser::Expr *originalKindParameter{nullptr };
360361 };
361362
362363 bool allowForwardReferenceToDerivedType () const {
@@ -365,8 +366,10 @@ class DeclTypeSpecVisitor : public AttrsVisitor {
365366 void set_allowForwardReferenceToDerivedType (bool yes) {
366367 state_.allowForwardReferenceToDerivedType = yes;
367368 }
369+ void set_inPDTDefinition (bool yes) { inPDTDefinition_ = yes; }
368370
369- const DeclTypeSpec *GetDeclTypeSpec ();
371+ const DeclTypeSpec *GetDeclTypeSpec () const ;
372+ const parser::Expr *GetOriginalKindParameter () const ;
370373 void BeginDeclTypeSpec ();
371374 void EndDeclTypeSpec ();
372375 void SetDeclTypeSpec (const DeclTypeSpec &);
@@ -380,6 +383,7 @@ class DeclTypeSpecVisitor : public AttrsVisitor {
380383
381384private:
382385 State state_;
386+ bool inPDTDefinition_{false };
383387
384388 void MakeNumericType (TypeCategory, int kind);
385389};
@@ -2454,9 +2458,12 @@ bool AttrsVisitor::Pre(const common::CUDADataAttr x) {
24542458
24552459// DeclTypeSpecVisitor implementation
24562460
2457- const DeclTypeSpec *DeclTypeSpecVisitor::GetDeclTypeSpec () {
2461+ const DeclTypeSpec *DeclTypeSpecVisitor::GetDeclTypeSpec () const {
24582462 return state_.declTypeSpec ;
24592463}
2464+ const parser::Expr *DeclTypeSpecVisitor::GetOriginalKindParameter () const {
2465+ return state_.originalKindParameter ;
2466+ }
24602467
24612468void DeclTypeSpecVisitor::BeginDeclTypeSpec () {
24622469 CHECK (!state_.expectDeclTypeSpec );
@@ -2541,6 +2548,21 @@ void DeclTypeSpecVisitor::SetDeclTypeSpec(const DeclTypeSpec &declTypeSpec) {
25412548
25422549KindExpr DeclTypeSpecVisitor::GetKindParamExpr (
25432550 TypeCategory category, const std::optional<parser::KindSelector> &kind) {
2551+ if (inPDTDefinition_) {
2552+ if (category != TypeCategory::Derived && kind) {
2553+ if (const auto *expr{
2554+ std::get_if<parser::ScalarIntConstantExpr>(&kind->u )}) {
2555+ CHECK (!state_.originalKindParameter );
2556+ // Save a pointer to the KIND= expression in the parse tree
2557+ // in case we need to reanalyze it during PDT instantiation.
2558+ state_.originalKindParameter = &expr->thing .thing .thing .value ();
2559+ }
2560+ }
2561+ // Inhibit some errors now that will be caught later during instantiations.
2562+ auto restorer{
2563+ context ().foldingContext ().AnalyzingPDTComponentKindSelector ()};
2564+ return AnalyzeKindSelector (context (), category, kind);
2565+ }
25442566 return AnalyzeKindSelector (context (), category, kind);
25452567}
25462568
@@ -6410,6 +6432,7 @@ bool DeclarationVisitor::Pre(const parser::DerivedTypeDef &x) {
64106432 details.set_isForwardReferenced (false );
64116433 derivedTypeInfo_ = {};
64126434 PopScope ();
6435+ set_inPDTDefinition (false );
64136436 return false ;
64146437}
64156438
@@ -6437,6 +6460,10 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
64376460 // component without producing spurious errors about already
64386461 // existing.
64396462 const Symbol &extendsSymbol{extendsType->typeSymbol ()};
6463+ if (extendsSymbol.scope () &&
6464+ extendsSymbol.scope ()->IsParameterizedDerivedType ()) {
6465+ set_inPDTDefinition (true );
6466+ }
64406467 auto restorer{common::ScopedSet (extendsName->symbol , nullptr )};
64416468 if (OkToAddComponent (*extendsName, &extendsSymbol)) {
64426469 auto &comp{DeclareEntity<ObjectEntityDetails>(*extendsName, Attrs{})};
@@ -6455,8 +6482,12 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
64556482 }
64566483 // Create symbols now for type parameters so that they shadow names
64576484 // from the enclosing specification part.
6485+ const auto ¶mNames{std::get<std::list<parser::Name>>(x.t )};
6486+ if (!paramNames.empty ()) {
6487+ set_inPDTDefinition (true );
6488+ }
64586489 if (auto *details{symbol.detailsIf <DerivedTypeDetails>()}) {
6459- for (const auto &name : std::get<std::list<parser::Name>>(x. t ) ) {
6490+ for (const auto &name : paramNames ) {
64606491 if (Symbol * symbol{MakeTypeSymbol (name, TypeParamDetails{})}) {
64616492 details->add_paramNameOrder (*symbol);
64626493 }
@@ -6544,8 +6575,7 @@ void DeclarationVisitor::Post(const parser::ComponentDecl &x) {
65446575 if (const auto *derived{declType->AsDerived ()}) {
65456576 if (!attrs.HasAny ({Attr::POINTER, Attr::ALLOCATABLE})) {
65466577 if (derivedTypeInfo_.type == &derived->typeSymbol ()) { // C744
6547- Say (" Recursive use of the derived type requires "
6548- " POINTER or ALLOCATABLE" _err_en_US);
6578+ Say (" Recursive use of the derived type requires POINTER or ALLOCATABLE" _err_en_US);
65496579 }
65506580 }
65516581 }
@@ -6558,7 +6588,11 @@ void DeclarationVisitor::Post(const parser::ComponentDecl &x) {
65586588 Initialization (name, *init, /* inComponentDecl=*/ true );
65596589 }
65606590 }
6561- currScope ().symbol ()->get <DerivedTypeDetails>().add_component (symbol);
6591+ auto &details{currScope ().symbol ()->get <DerivedTypeDetails>()};
6592+ details.add_component (symbol);
6593+ if (const parser::Expr *kindExpr{GetOriginalKindParameter ()}) {
6594+ details.add_originalKindParameter (name.source , kindExpr);
6595+ }
65626596 }
65636597 ClearArraySpec ();
65646598 ClearCoarraySpec ();
0 commit comments