@@ -357,6 +357,7 @@ class DeclTypeSpecVisitor : public AttrsVisitor {
357
357
DeclTypeSpec::Category category{DeclTypeSpec::TypeDerived};
358
358
} derived;
359
359
bool allowForwardReferenceToDerivedType{false };
360
+ const parser::Expr *originalKindParameter{nullptr };
360
361
};
361
362
362
363
bool allowForwardReferenceToDerivedType () const {
@@ -365,8 +366,10 @@ class DeclTypeSpecVisitor : public AttrsVisitor {
365
366
void set_allowForwardReferenceToDerivedType (bool yes) {
366
367
state_.allowForwardReferenceToDerivedType = yes;
367
368
}
369
+ void set_inPDTDefinition (bool yes) { inPDTDefinition_ = yes; }
368
370
369
- const DeclTypeSpec *GetDeclTypeSpec ();
371
+ const DeclTypeSpec *GetDeclTypeSpec () const ;
372
+ const parser::Expr *GetOriginalKindParameter () const ;
370
373
void BeginDeclTypeSpec ();
371
374
void EndDeclTypeSpec ();
372
375
void SetDeclTypeSpec (const DeclTypeSpec &);
@@ -380,6 +383,7 @@ class DeclTypeSpecVisitor : public AttrsVisitor {
380
383
381
384
private:
382
385
State state_;
386
+ bool inPDTDefinition_{false };
383
387
384
388
void MakeNumericType (TypeCategory, int kind);
385
389
};
@@ -2454,9 +2458,12 @@ bool AttrsVisitor::Pre(const common::CUDADataAttr x) {
2454
2458
2455
2459
// DeclTypeSpecVisitor implementation
2456
2460
2457
- const DeclTypeSpec *DeclTypeSpecVisitor::GetDeclTypeSpec () {
2461
+ const DeclTypeSpec *DeclTypeSpecVisitor::GetDeclTypeSpec () const {
2458
2462
return state_.declTypeSpec ;
2459
2463
}
2464
+ const parser::Expr *DeclTypeSpecVisitor::GetOriginalKindParameter () const {
2465
+ return state_.originalKindParameter ;
2466
+ }
2460
2467
2461
2468
void DeclTypeSpecVisitor::BeginDeclTypeSpec () {
2462
2469
CHECK (!state_.expectDeclTypeSpec );
@@ -2541,6 +2548,21 @@ void DeclTypeSpecVisitor::SetDeclTypeSpec(const DeclTypeSpec &declTypeSpec) {
2541
2548
2542
2549
KindExpr DeclTypeSpecVisitor::GetKindParamExpr (
2543
2550
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
+ }
2544
2566
return AnalyzeKindSelector (context (), category, kind);
2545
2567
}
2546
2568
@@ -6410,6 +6432,7 @@ bool DeclarationVisitor::Pre(const parser::DerivedTypeDef &x) {
6410
6432
details.set_isForwardReferenced (false );
6411
6433
derivedTypeInfo_ = {};
6412
6434
PopScope ();
6435
+ set_inPDTDefinition (false );
6413
6436
return false ;
6414
6437
}
6415
6438
@@ -6437,6 +6460,10 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
6437
6460
// component without producing spurious errors about already
6438
6461
// existing.
6439
6462
const Symbol &extendsSymbol{extendsType->typeSymbol ()};
6463
+ if (extendsSymbol.scope () &&
6464
+ extendsSymbol.scope ()->IsParameterizedDerivedType ()) {
6465
+ set_inPDTDefinition (true );
6466
+ }
6440
6467
auto restorer{common::ScopedSet (extendsName->symbol , nullptr )};
6441
6468
if (OkToAddComponent (*extendsName, &extendsSymbol)) {
6442
6469
auto &comp{DeclareEntity<ObjectEntityDetails>(*extendsName, Attrs{})};
@@ -6455,8 +6482,12 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
6455
6482
}
6456
6483
// Create symbols now for type parameters so that they shadow names
6457
6484
// 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
+ }
6458
6489
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 ) {
6460
6491
if (Symbol * symbol{MakeTypeSymbol (name, TypeParamDetails{})}) {
6461
6492
details->add_paramNameOrder (*symbol);
6462
6493
}
@@ -6544,8 +6575,7 @@ void DeclarationVisitor::Post(const parser::ComponentDecl &x) {
6544
6575
if (const auto *derived{declType->AsDerived ()}) {
6545
6576
if (!attrs.HasAny ({Attr::POINTER, Attr::ALLOCATABLE})) {
6546
6577
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);
6549
6579
}
6550
6580
}
6551
6581
}
@@ -6558,7 +6588,11 @@ void DeclarationVisitor::Post(const parser::ComponentDecl &x) {
6558
6588
Initialization (name, *init, /* inComponentDecl=*/ true );
6559
6589
}
6560
6590
}
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
+ }
6562
6596
}
6563
6597
ClearArraySpec ();
6564
6598
ClearCoarraySpec ();
0 commit comments