@@ -955,7 +955,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
955
955
void Post (const parser::TargetStmt &) { objectDeclAttr_ = std::nullopt; }
956
956
void Post (const parser::DimensionStmt::Declaration &);
957
957
void Post (const parser::CodimensionDecl &);
958
- bool Pre (const parser::TypeDeclarationStmt &) { return BeginDecl (); }
958
+ bool Pre (const parser::TypeDeclarationStmt &);
959
959
void Post (const parser::TypeDeclarationStmt &);
960
960
void Post (const parser::IntegerTypeSpec &);
961
961
void Post (const parser::IntrinsicTypeSpec::Real &);
@@ -1202,6 +1202,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
1202
1202
bool MustBeScalar (const Symbol &symbol) const {
1203
1203
return mustBeScalar_.find (symbol) != mustBeScalar_.end ();
1204
1204
}
1205
+ void DeclareIntrinsic (const parser::Name &);
1205
1206
};
1206
1207
1207
1208
// Resolve construct entities and statement entities.
@@ -4550,6 +4551,20 @@ void DeclarationVisitor::CheckAccessibility(
4550
4551
}
4551
4552
}
4552
4553
4554
+ bool DeclarationVisitor::Pre (const parser::TypeDeclarationStmt &x) {
4555
+ BeginDecl ();
4556
+ // If INTRINSIC appears as an attr-spec, handle it now as if the
4557
+ // names had appeared on an INTRINSIC attribute statement beforehand.
4558
+ for (const auto &attr : std::get<std::list<parser::AttrSpec>>(x.t )) {
4559
+ if (std::holds_alternative<parser::Intrinsic>(attr.u )) {
4560
+ for (const auto &decl : std::get<std::list<parser::EntityDecl>>(x.t )) {
4561
+ DeclareIntrinsic (parser::GetFirstName (decl));
4562
+ }
4563
+ break ;
4564
+ }
4565
+ }
4566
+ return true ;
4567
+ }
4553
4568
void DeclarationVisitor::Post (const parser::TypeDeclarationStmt &) {
4554
4569
EndDecl ();
4555
4570
}
@@ -4571,6 +4586,7 @@ bool DeclarationVisitor::Pre(const parser::Initialization &) {
4571
4586
void DeclarationVisitor::Post (const parser::EntityDecl &x) {
4572
4587
const auto &name{std::get<parser::ObjectName>(x.t )};
4573
4588
Attrs attrs{attrs_ ? HandleSaveName (name.source , *attrs_) : Attrs{}};
4589
+ attrs.set (Attr::INTRINSIC, false ); // dealt with in Pre(TypeDeclarationStmt)
4574
4590
Symbol &symbol{DeclareUnknownEntity (name, attrs)};
4575
4591
symbol.ReplaceName (name.source );
4576
4592
SetCUDADataAttr (name.source , symbol, cudaDataAttr ());
@@ -4811,45 +4827,47 @@ bool DeclarationVisitor::Pre(const parser::IntentStmt &x) {
4811
4827
HandleAttributeStmt (IntentSpecToAttr (intentSpec), names);
4812
4828
}
4813
4829
bool DeclarationVisitor::Pre (const parser::IntrinsicStmt &x) {
4814
- HandleAttributeStmt (Attr::INTRINSIC, x.v );
4815
4830
for (const auto &name : x.v ) {
4816
- if (!IsIntrinsic (name.source , std::nullopt)) {
4817
- Say (name.source , " '%s' is not a known intrinsic procedure" _err_en_US);
4818
- }
4819
- auto &symbol{DEREF (FindSymbol (name))};
4820
- if (symbol.has <GenericDetails>()) {
4821
- // Generic interface is extending intrinsic; ok
4822
- } else if (!ConvertToProcEntity (symbol)) {
4823
- SayWithDecl (
4824
- name, symbol, " INTRINSIC attribute not allowed on '%s'" _err_en_US);
4825
- } else if (symbol.attrs ().test (Attr::EXTERNAL)) { // C840
4831
+ DeclareIntrinsic (name);
4832
+ }
4833
+ return false ;
4834
+ }
4835
+ void DeclarationVisitor::DeclareIntrinsic (const parser::Name &name) {
4836
+ HandleAttributeStmt (Attr::INTRINSIC, name);
4837
+ if (!IsIntrinsic (name.source , std::nullopt)) {
4838
+ Say (name.source , " '%s' is not a known intrinsic procedure" _err_en_US);
4839
+ }
4840
+ auto &symbol{DEREF (FindSymbol (name))};
4841
+ if (symbol.has <GenericDetails>()) {
4842
+ // Generic interface is extending intrinsic; ok
4843
+ } else if (!ConvertToProcEntity (symbol)) {
4844
+ SayWithDecl (
4845
+ name, symbol, " INTRINSIC attribute not allowed on '%s'" _err_en_US);
4846
+ } else if (symbol.attrs ().test (Attr::EXTERNAL)) { // C840
4847
+ Say (symbol.name (),
4848
+ " Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes" _err_en_US,
4849
+ symbol.name ());
4850
+ } else {
4851
+ if (symbol.GetType ()) {
4852
+ // These warnings are worded so that they should make sense in either
4853
+ // order.
4826
4854
Say (symbol.name (),
4827
- " Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes" _err_en_US,
4828
- symbol.name ());
4829
- } else {
4830
- if (symbol.GetType ()) {
4831
- // These warnings are worded so that they should make sense in either
4832
- // order.
4833
- Say (symbol.name (),
4834
- " Explicit type declaration ignored for intrinsic function '%s'" _warn_en_US,
4835
- symbol.name ())
4836
- .Attach (name.source ,
4837
- " INTRINSIC statement for explicitly-typed '%s'" _en_US,
4838
- name.source );
4839
- }
4840
- if (!symbol.test (Symbol::Flag::Function) &&
4841
- !symbol.test (Symbol::Flag::Subroutine)) {
4842
- if (context ().intrinsics ().IsIntrinsicFunction (
4843
- name.source .ToString ())) {
4844
- symbol.set (Symbol::Flag::Function);
4845
- } else if (context ().intrinsics ().IsIntrinsicSubroutine (
4846
- name.source .ToString ())) {
4847
- symbol.set (Symbol::Flag::Subroutine);
4848
- }
4855
+ " Explicit type declaration ignored for intrinsic function '%s'" _warn_en_US,
4856
+ symbol.name ())
4857
+ .Attach (name.source ,
4858
+ " INTRINSIC statement for explicitly-typed '%s'" _en_US,
4859
+ name.source );
4860
+ }
4861
+ if (!symbol.test (Symbol::Flag::Function) &&
4862
+ !symbol.test (Symbol::Flag::Subroutine)) {
4863
+ if (context ().intrinsics ().IsIntrinsicFunction (name.source .ToString ())) {
4864
+ symbol.set (Symbol::Flag::Function);
4865
+ } else if (context ().intrinsics ().IsIntrinsicSubroutine (
4866
+ name.source .ToString ())) {
4867
+ symbol.set (Symbol::Flag::Subroutine);
4849
4868
}
4850
4869
}
4851
4870
}
4852
- return false ;
4853
4871
}
4854
4872
bool DeclarationVisitor::Pre (const parser::OptionalStmt &x) {
4855
4873
return CheckNotInBlock (" OPTIONAL" ) && // C1107
0 commit comments