56 const llvm::omp::Clauses &ompRequires()
const {
return ompRequires_; }
57 void set_ompRequires(llvm::omp::Clauses clauses) { ompRequires_ = clauses; }
59 const std::optional<common::OmpMemoryOrderType> &
60 ompAtomicDefaultMemOrder()
const {
61 return ompAtomicDefaultMemOrder_;
63 void set_ompAtomicDefaultMemOrder(common::OmpMemoryOrderType flags) {
64 ompAtomicDefaultMemOrder_ = flags;
67 const llvm::omp::Clauses &ompDeclTarget()
const {
return ompDeclTarget_; }
68 void set_ompDeclTarget(llvm::omp::Clauses clauses) {
69 ompDeclTarget_ = clauses;
72 const std::optional<common::OmpDeviceType> &ompDeclTargetDeviceType()
const {
73 return ompDeclTargetDeviceType_;
75 void set_ompDeclTarget(common::OmpDeviceType device) {
76 ompDeclTargetDeviceType_ = device;
79 const llvm::omp::Clauses &ompGroupprivate()
const {
return ompGroupprivate_; }
80 void set_ompGroupprivate(llvm::omp::Clauses clauses) {
81 ompGroupprivate_ = clauses;
84 const std::optional<common::OmpDeviceType> &
85 ompGroupprivateDeviceType()
const {
86 return ompGroupprivateDeviceType_;
88 void set_ompGroupprivate(common::OmpDeviceType device) {
89 ompGroupprivateDeviceType_ = device;
94 void printClauseSet(llvm::raw_ostream &os,
const llvm::omp::Clauses &clauses,
95 llvm::omp::Directive dir,
97 friend llvm::raw_ostream &operator<<(
100 void set_version(llvm::omp::Version version) { version_ = version; }
103 llvm::omp::Version version_;
108 llvm::omp::Clauses ompRequires_;
111 std::optional<common::OmpMemoryOrderType> ompAtomicDefaultMemOrder_;
114 llvm::omp::Clauses ompDeclTarget_;
117 std::optional<common::OmpDeviceType> ompDeclTargetDeviceType_;
119 llvm::omp::Clauses ompGroupprivate_;
122 std::optional<common::OmpDeviceType> ompGroupprivateDeviceType_;
174class OpenACCRoutineDeviceTypeInfo {
176 explicit OpenACCRoutineDeviceTypeInfo(
177 Fortran::common::OpenACCDeviceType dType)
178 : deviceType_{dType} {}
179 bool isSeq()
const {
return isSeq_; }
180 void set_isSeq(
bool value =
true) { isSeq_ = value; }
181 bool isVector()
const {
return isVector_; }
182 void set_isVector(
bool value =
true) { isVector_ = value; }
183 bool isWorker()
const {
return isWorker_; }
184 void set_isWorker(
bool value =
true) { isWorker_ = value; }
185 bool isGang()
const {
return isGang_; }
186 void set_isGang(
bool value =
true) { isGang_ = value; }
187 unsigned gangDim()
const {
return gangDim_; }
188 void set_gangDim(
unsigned value) { gangDim_ = value; }
189 const std::variant<std::string, SymbolRef> *bindName()
const {
190 return bindName_.has_value() ? &*bindName_ :
nullptr;
192 const std::optional<std::variant<std::string, SymbolRef>> &
193 bindNameOpt()
const {
196 void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
197 void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
199 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
201 friend llvm::raw_ostream &operator<<(
202 llvm::raw_ostream &,
const OpenACCRoutineDeviceTypeInfo &);
206 bool isVector_{
false};
207 bool isWorker_{
false};
209 unsigned gangDim_{0};
212 std::optional<std::variant<std::string, SymbolRef>> bindName_;
213 Fortran::common::OpenACCDeviceType deviceType_{
214 Fortran::common::OpenACCDeviceType::None};
255 bool isFunction()
const {
return result_ !=
nullptr; }
256 bool isInterface()
const {
return isInterface_; }
257 void set_isInterface(
bool value =
true) { isInterface_ = value; }
258 bool isDummy()
const {
return isDummy_; }
259 void set_isDummy(
bool value =
true) { isDummy_ = value; }
260 Scope *entryScope() {
return entryScope_; }
261 const Scope *entryScope()
const {
return entryScope_; }
262 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
263 const Symbol &result()
const {
267 void set_result(
Symbol &result) {
271 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
272 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
273 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
274 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
275 void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
276 Symbol *moduleInterface() {
return moduleInterface_; }
277 const Symbol *moduleInterface()
const {
return moduleInterface_; }
278 void set_moduleInterface(
Symbol &);
279 void ReplaceResult(
Symbol &result) {
280 CHECK(result_ !=
nullptr);
283 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
284 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
285 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
286 return cudaSubprogramAttrs_;
288 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
289 cudaSubprogramAttrs_ = csas;
291 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
292 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
293 return cudaLaunchBounds_;
295 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
296 cudaLaunchBounds_ = std::move(x);
298 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
299 const std::vector<std::int64_t> &cudaClusterDims()
const {
300 return cudaClusterDims_;
302 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
303 cudaClusterDims_ = std::move(x);
305 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
306 return openACCRoutineInfos_;
309 openACCRoutineInfos_.push_back(info);
312 const std::vector<OmpDeclareVariantEntry> &ompDeclareVariants()
const {
313 return ompDeclareVariants_;
316 ompDeclareVariants_.push_back(std::move(entry));
320 bool isInterface_{
false};
321 bool isDummy_{
false};
322 std::vector<Symbol *> dummyArgs_;
324 Scope *entryScope_{
nullptr};
325 MaybeExpr stmtFunction_;
329 Symbol *moduleInterface_{
nullptr};
330 bool defaultIgnoreTKR_{
false};
332 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
334 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
336 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
337 std::vector<OmpDeclareVariantEntry> ompDeclareVariants_;
339 friend llvm::raw_ostream &operator<<(
431 explicit ObjectEntityDetails(EntityDetails &&);
432 ObjectEntityDetails(
const ObjectEntityDetails &) =
default;
433 ObjectEntityDetails(ObjectEntityDetails &&) =
default;
434 ObjectEntityDetails &operator=(
const ObjectEntityDetails &) =
default;
435 ObjectEntityDetails(
bool isDummy =
false) : EntityDetails(isDummy) {}
436 MaybeExpr &init() {
return init_; }
437 const MaybeExpr &init()
const {
return init_; }
438 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
439 const parser::Expr *unanalyzedPDTComponentInit()
const {
440 return unanalyzedPDTComponentInit_;
442 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
443 unanalyzedPDTComponentInit_ = expr;
446 const ArraySpec &shape()
const {
return shape_; }
447 ArraySpec &coshape() {
return coshape_; }
448 const ArraySpec &coshape()
const {
return coshape_; }
451 const Symbol *commonBlock()
const {
return commonBlock_; }
452 void set_commonBlock(
const Symbol &commonBlock) {
453 commonBlock_ = &commonBlock;
455 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
456 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
457 bool IsArray()
const {
return !shape_.empty(); }
458 bool IsCoarray()
const {
return !coshape_.empty(); }
459 bool IsAssumedShape()
const {
460 return isDummy() && shape_.CanBeAssumedShape();
462 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
463 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
464 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
465 return cudaDataAttr_;
467 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
468 cudaDataAttr_ = attr;
470 bool cudaDataAttrIsImplicit()
const {
return cudaDataAttrIsImplicit_; }
471 void set_cudaDataAttrIsImplicit(
bool yes =
true) {
472 cudaDataAttrIsImplicit_ = yes;
478 void add_droppedBoundToCheck(
Bound &&bound) {
479 droppedBoundsToCheck_.emplace_back(std::move(bound));
481 const std::vector<Bound> &droppedBoundsToCheck()
const {
482 return droppedBoundsToCheck_;
487 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
490 std::vector<Bound> droppedBoundsToCheck_;
491 common::IgnoreTKRSet ignoreTKR_;
492 const Symbol *commonBlock_{
nullptr};
493 std::optional<common::CUDADataAttr> cudaDataAttr_;
494 bool cudaDataAttrIsImplicit_{
false};
496 friend llvm::raw_ostream &operator<<(
497 llvm::raw_ostream &,
const ObjectEntityDetails &);
517class ProcEntityDetails :
public EntityDetails,
521 ProcEntityDetails() =
default;
522 explicit ProcEntityDetails(EntityDetails &&);
523 ProcEntityDetails(
const ProcEntityDetails &) =
default;
524 ProcEntityDetails(ProcEntityDetails &&) =
default;
525 ProcEntityDetails &operator=(
const ProcEntityDetails &) =
default;
527 const Symbol *rawProcInterface()
const {
return rawProcInterface_; }
528 const Symbol *procInterface()
const {
return procInterface_; }
529 void set_procInterfaces(
const Symbol &raw,
const Symbol &resolved) {
530 rawProcInterface_ = &raw;
531 procInterface_ = &resolved;
533 inline bool HasExplicitInterface()
const;
537 std::optional<const Symbol *> init()
const {
return init_; }
538 void set_init(
const Symbol &symbol) { init_ = &symbol; }
539 void set_init(std::nullptr_t) { init_ =
nullptr; }
540 bool isCUDAKernel()
const {
return isCUDAKernel_; }
541 void set_isCUDAKernel(
bool yes =
true) { isCUDAKernel_ = yes; }
542 std::optional<SourceName> usedAsProcedureHere()
const {
543 return usedAsProcedureHere_;
545 void set_usedAsProcedureHere(SourceName here) { usedAsProcedureHere_ = here; }
546 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
547 return openACCRoutineInfos_;
550 openACCRoutineInfos_.push_back(info);
554 const Symbol *rawProcInterface_{
nullptr};
555 const Symbol *procInterface_{
nullptr};
556 std::optional<const Symbol *> init_;
557 bool isCUDAKernel_{
false};
558 std::optional<SourceName> usedAsProcedureHere_;
559 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
560 friend llvm::raw_ostream &operator<<(
561 llvm::raw_ostream &,
const ProcEntityDetails &);
571 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
572 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
573 bool sequence()
const {
return sequence_; }
574 bool isDECStructure()
const {
return isDECStructure_; }
575 bool isEnumerationType()
const {
return isEnumerationType_; }
576 void set_isEnumerationType(
bool x =
true) { isEnumerationType_ = x; }
577 std::optional<Attr> enumeratorDefaultAccess()
const {
578 return enumeratorDefaultAccess_;
580 void set_enumeratorDefaultAccess(Attr a) { enumeratorDefaultAccess_ = a; }
583 static constexpr char ordinalComponentName[]{
"__ordinal"};
584 int enumeratorCount()
const {
return enumeratorCount_; }
585 void set_enumeratorCount(
int n) { enumeratorCount_ = n; }
586 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
587 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
588 bool isForwardReferenced()
const {
return isForwardReferenced_; }
589 void add_paramNameOrder(
const Symbol &symbol) {
590 paramNameOrder_.push_back(symbol);
592 void add_paramDeclOrder(
const Symbol &symbol) {
593 paramDeclOrder_.push_back(symbol);
595 void add_component(
const Symbol &);
596 void set_sequence(
bool x =
true) { sequence_ = x; }
597 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
598 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
599 const std::list<SourceName> &componentNames()
const {
600 return componentNames_;
602 const std::map<SourceName, const parser::Expr *> &
603 originalKindParameterMap()
const {
604 return originalKindParameterMap_;
606 void add_originalKindParameter(SourceName,
const parser::Expr *);
609 const Symbol *GetParentComponent(
const Scope &)
const;
611 std::optional<SourceName> GetParentComponentName()
const {
612 if (componentNames_.empty()) {
615 return componentNames_.front();
619 const Symbol *GetFinalForRank(
int)
const;
626 SymbolVector paramNameOrder_;
627 SymbolVector paramDeclOrder_;
630 std::list<SourceName> componentNames_;
631 std::map<SourceName, SymbolRef> finals_;
632 bool sequence_{
false};
633 bool isDECStructure_{
false};
634 bool isForwardReferenced_{
false};
635 std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
638 bool isEnumerationType_{
false};
639 int enumeratorCount_{0};
640 std::optional<Attr> enumeratorDefaultAccess_;
642 friend llvm::raw_ostream &operator<<(
926 CrayPointer, CrayPointee,
945 AccPrivate, AccFirstPrivate, AccShared,
947 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
948 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
954 AccDevice, AccHost, AccSelf,
956 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
958 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
961 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
962 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
964 OmpCopyIn, OmpCopyPrivate,
966 OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
968 OmpReserved, OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned,
969 OmpNontemporal, OmpAllocate, OmpDeclarativeAllocateDirective,
970 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
971 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
972 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
973 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
977 const Scope &owner()
const {
return *owner_; }
978 const SourceName &name()
const {
return name_; }
979 Attrs &attrs() {
return attrs_; }
980 const Attrs &attrs()
const {
return attrs_; }
981 Attrs &implicitAttrs() {
return implicitAttrs_; }
982 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
983 Flags &flags() {
return flags_; }
984 const Flags &flags()
const {
return flags_; }
985 bool test(Flag flag)
const {
return flags_.test(flag); }
986 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
988 Scope *scope() {
return scope_; }
989 const Scope *scope()
const {
return scope_; }
990 void set_scope(Scope *scope) { scope_ = scope; }
991 std::size_t size()
const {
return size_; }
992 void set_size(std::size_t size) { size_ = size; }
993 std::size_t offset()
const {
return offset_; }
994 void set_offset(std::size_t offset) { offset_ = offset; }
996 void ReplaceName(
const SourceName &);
997 static std::string OmpFlagToClauseName(Flag ompFlag);
1000 template <
typename D>
bool has()
const {
1001 return std::holds_alternative<D>(details_);
1005 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
1006 template <
typename D>
const D *detailsIf()
const {
1007 return std::get_if<D>(&details_);
1011 template <
typename D> D &get() {
1012 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
1014 template <
typename D>
const D &get()
const {
1015 const auto *p{detailsIf<D>()};
1020 Details &details() {
return details_; }
1021 const Details &details()
const {
return details_; }
1024 void set_details(Details &&);
1027 bool CanReplaceDetails(
const Details &details)
const;
1030 inline Symbol &GetUltimate();
1031 inline const Symbol &GetUltimate()
const;
1033 inline DeclTypeSpec *GetType();
1034 inline const DeclTypeSpec *GetType()
const;
1035 void SetType(
const DeclTypeSpec &);
1037 const std::string *GetBindName()
const;
1038 void SetBindName(std::string &&);
1039 bool GetIsExplicitBindName()
const;
1040 void SetIsExplicitBindName(
bool);
1041 void SetIsCDefined(
bool);
1042 bool IsFuncResult()
const;
1043 bool IsObjectArray()
const;
1044 const ArraySpec *GetShape()
const;
1045 bool IsSubprogram()
const;
1046 bool IsFromModFile()
const;
1047 bool HasExplicitInterface()
const {
1048 return common::visit(
1050 [](
const SubprogramDetails &) {
return true; },
1051 [](
const SubprogramNameDetails &) {
return true; },
1052 [&](
const ProcEntityDetails &x) {
1053 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
1055 [](
const ProcBindingDetails &x) {
1056 return x.symbol().HasExplicitInterface();
1058 [](
const UseDetails &x) {
1059 return x.symbol().HasExplicitInterface();
1061 [](
const HostAssocDetails &x) {
1062 return x.symbol().HasExplicitInterface();
1064 [](
const GenericDetails &x) {
1065 return x.specific() && x.specific()->HasExplicitInterface();
1067 [](
const auto &) {
return false; },
1071 bool HasLocalLocality()
const {
1072 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
1075 bool operator==(
const Symbol &that)
const {
return this == &that; }
1076 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
1078 int Rank()
const {
return RankImpl(); }
1079 int Corank()
const {
return CorankImpl(); }
1084 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
1089 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
1091 SemanticsContext &GetSemanticsContext()
const;
1092#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1093 LLVM_DUMP_METHOD
void dump()
const;
1097 const Scope *owner_;
1100 Attrs implicitAttrs_;
1102 Scope *scope_{
nullptr};
1103 std::size_t size_{0};
1104 std::size_t offset_{0};
1108 std::string GetDetailsName()
const;
1109 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
1110 friend llvm::raw_ostream &DumpForUnparse(
1111 llvm::raw_ostream &,
const Symbol &,
bool);
1113 static constexpr int startRecursionDepth{100};
1115 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
1116 inline int RankImpl(
int depth = startRecursionDepth)
const {
1120 return common::visit(
1122 [&](
const SubprogramDetails &sd) {
1123 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
1125 [](
const GenericDetails &) {
1128 [&](
const ProcBindingDetails &x) {
1129 return x.symbol().RankImpl(depth);
1131 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
1132 [&](
const HostAssocDetails &x) {
1133 return x.symbol().RankImpl(depth);
1135 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1136 [&](
const ProcEntityDetails &ped) {
1137 const Symbol *iface{ped.procInterface()};
1138 return iface ? iface->RankImpl(depth) : 0;
1140 [](
const AssocEntityDetails &aed) {
1141 if (
auto assocRank{aed.rank()}) {
1144 }
else if (aed.IsAssumedRank()) {
1147 }
else if (
const auto &expr{aed.expr()}) {
1148 return expr->Rank();
1153 [](
const auto &) {
return 0; },
1157 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1161 return common::visit(
1163 [&](
const SubprogramDetails &sd) {
1164 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1166 [](
const GenericDetails &) {
return 0; },
1167 [&](
const ProcEntityDetails &ped) {
1168 const Symbol *iface{ped.procInterface()};
1169 return iface ? iface->CorankImpl(depth) : 0;
1171 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1172 [&](
const HostAssocDetails &x) {
1173 return x.symbol().CorankImpl(depth);
1175 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1176 [](
const AssocEntityDetails &aed) {
1177 return aed.expr() ? aed.expr()->Corank() : 0;
1179 [](
const auto &) {
return 0; },
1183 template <std::
size_t>
friend class Symbols;
1184 template <
class, std::
size_t>
friend class std::array;