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;
474 void add_droppedBoundToCheck(
Bound &&bound) {
475 droppedBoundsToCheck_.emplace_back(std::move(bound));
477 const std::vector<Bound> &droppedBoundsToCheck()
const {
478 return droppedBoundsToCheck_;
483 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
486 std::vector<Bound> droppedBoundsToCheck_;
487 common::IgnoreTKRSet ignoreTKR_;
488 const Symbol *commonBlock_{
nullptr};
489 std::optional<common::CUDADataAttr> cudaDataAttr_;
490 friend llvm::raw_ostream &operator<<(
491 llvm::raw_ostream &,
const ObjectEntityDetails &);
511class ProcEntityDetails :
public EntityDetails,
515 ProcEntityDetails() =
default;
516 explicit ProcEntityDetails(EntityDetails &&);
517 ProcEntityDetails(
const ProcEntityDetails &) =
default;
518 ProcEntityDetails(ProcEntityDetails &&) =
default;
519 ProcEntityDetails &operator=(
const ProcEntityDetails &) =
default;
521 const Symbol *rawProcInterface()
const {
return rawProcInterface_; }
522 const Symbol *procInterface()
const {
return procInterface_; }
523 void set_procInterfaces(
const Symbol &raw,
const Symbol &resolved) {
524 rawProcInterface_ = &raw;
525 procInterface_ = &resolved;
527 inline bool HasExplicitInterface()
const;
531 std::optional<const Symbol *> init()
const {
return init_; }
532 void set_init(
const Symbol &symbol) { init_ = &symbol; }
533 void set_init(std::nullptr_t) { init_ =
nullptr; }
534 bool isCUDAKernel()
const {
return isCUDAKernel_; }
535 void set_isCUDAKernel(
bool yes =
true) { isCUDAKernel_ = yes; }
536 std::optional<SourceName> usedAsProcedureHere()
const {
537 return usedAsProcedureHere_;
539 void set_usedAsProcedureHere(SourceName here) { usedAsProcedureHere_ = here; }
540 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
541 return openACCRoutineInfos_;
544 openACCRoutineInfos_.push_back(info);
548 const Symbol *rawProcInterface_{
nullptr};
549 const Symbol *procInterface_{
nullptr};
550 std::optional<const Symbol *> init_;
551 bool isCUDAKernel_{
false};
552 std::optional<SourceName> usedAsProcedureHere_;
553 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
554 friend llvm::raw_ostream &operator<<(
555 llvm::raw_ostream &,
const ProcEntityDetails &);
565 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
566 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
567 bool sequence()
const {
return sequence_; }
568 bool isDECStructure()
const {
return isDECStructure_; }
569 bool isEnumerationType()
const {
return isEnumerationType_; }
570 void set_isEnumerationType(
bool x =
true) { isEnumerationType_ = x; }
571 std::optional<Attr> enumeratorDefaultAccess()
const {
572 return enumeratorDefaultAccess_;
574 void set_enumeratorDefaultAccess(Attr a) { enumeratorDefaultAccess_ = a; }
577 static constexpr char ordinalComponentName[]{
"__ordinal"};
578 int enumeratorCount()
const {
return enumeratorCount_; }
579 void set_enumeratorCount(
int n) { enumeratorCount_ = n; }
580 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
581 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
582 bool isForwardReferenced()
const {
return isForwardReferenced_; }
583 void add_paramNameOrder(
const Symbol &symbol) {
584 paramNameOrder_.push_back(symbol);
586 void add_paramDeclOrder(
const Symbol &symbol) {
587 paramDeclOrder_.push_back(symbol);
589 void add_component(
const Symbol &);
590 void set_sequence(
bool x =
true) { sequence_ = x; }
591 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
592 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
593 const std::list<SourceName> &componentNames()
const {
594 return componentNames_;
596 const std::map<SourceName, const parser::Expr *> &
597 originalKindParameterMap()
const {
598 return originalKindParameterMap_;
600 void add_originalKindParameter(SourceName,
const parser::Expr *);
603 const Symbol *GetParentComponent(
const Scope &)
const;
605 std::optional<SourceName> GetParentComponentName()
const {
606 if (componentNames_.empty()) {
609 return componentNames_.front();
613 const Symbol *GetFinalForRank(
int)
const;
620 SymbolVector paramNameOrder_;
621 SymbolVector paramDeclOrder_;
624 std::list<SourceName> componentNames_;
625 std::map<SourceName, SymbolRef> finals_;
626 bool sequence_{
false};
627 bool isDECStructure_{
false};
628 bool isForwardReferenced_{
false};
629 std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
632 bool isEnumerationType_{
false};
633 int enumeratorCount_{0};
634 std::optional<Attr> enumeratorDefaultAccess_;
636 friend llvm::raw_ostream &operator<<(
920 CrayPointer, CrayPointee,
939 AccPrivate, AccFirstPrivate, AccShared,
941 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
942 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
948 AccDevice, AccHost, AccSelf,
950 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
952 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
955 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
956 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
958 OmpCopyIn, OmpCopyPrivate,
960 OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
962 OmpReserved, OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned,
963 OmpNontemporal, OmpAllocate, OmpDeclarativeAllocateDirective,
964 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
965 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
966 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
967 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
971 const Scope &owner()
const {
return *owner_; }
972 const SourceName &name()
const {
return name_; }
973 Attrs &attrs() {
return attrs_; }
974 const Attrs &attrs()
const {
return attrs_; }
975 Attrs &implicitAttrs() {
return implicitAttrs_; }
976 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
977 Flags &flags() {
return flags_; }
978 const Flags &flags()
const {
return flags_; }
979 bool test(Flag flag)
const {
return flags_.test(flag); }
980 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
982 Scope *scope() {
return scope_; }
983 const Scope *scope()
const {
return scope_; }
984 void set_scope(Scope *scope) { scope_ = scope; }
985 std::size_t size()
const {
return size_; }
986 void set_size(std::size_t size) { size_ = size; }
987 std::size_t offset()
const {
return offset_; }
988 void set_offset(std::size_t offset) { offset_ = offset; }
990 void ReplaceName(
const SourceName &);
991 static std::string OmpFlagToClauseName(Flag ompFlag);
994 template <
typename D>
bool has()
const {
995 return std::holds_alternative<D>(details_);
999 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
1000 template <
typename D>
const D *detailsIf()
const {
1001 return std::get_if<D>(&details_);
1005 template <
typename D> D &get() {
1006 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
1008 template <
typename D>
const D &get()
const {
1009 const auto *p{detailsIf<D>()};
1014 Details &details() {
return details_; }
1015 const Details &details()
const {
return details_; }
1018 void set_details(Details &&);
1021 bool CanReplaceDetails(
const Details &details)
const;
1024 inline Symbol &GetUltimate();
1025 inline const Symbol &GetUltimate()
const;
1027 inline DeclTypeSpec *GetType();
1028 inline const DeclTypeSpec *GetType()
const;
1029 void SetType(
const DeclTypeSpec &);
1031 const std::string *GetBindName()
const;
1032 void SetBindName(std::string &&);
1033 bool GetIsExplicitBindName()
const;
1034 void SetIsExplicitBindName(
bool);
1035 void SetIsCDefined(
bool);
1036 bool IsFuncResult()
const;
1037 bool IsObjectArray()
const;
1038 const ArraySpec *GetShape()
const;
1039 bool IsSubprogram()
const;
1040 bool IsFromModFile()
const;
1041 bool HasExplicitInterface()
const {
1042 return common::visit(
1044 [](
const SubprogramDetails &) {
return true; },
1045 [](
const SubprogramNameDetails &) {
return true; },
1046 [&](
const ProcEntityDetails &x) {
1047 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
1049 [](
const ProcBindingDetails &x) {
1050 return x.symbol().HasExplicitInterface();
1052 [](
const UseDetails &x) {
1053 return x.symbol().HasExplicitInterface();
1055 [](
const HostAssocDetails &x) {
1056 return x.symbol().HasExplicitInterface();
1058 [](
const GenericDetails &x) {
1059 return x.specific() && x.specific()->HasExplicitInterface();
1061 [](
const auto &) {
return false; },
1065 bool HasLocalLocality()
const {
1066 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
1069 bool operator==(
const Symbol &that)
const {
return this == &that; }
1070 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
1072 int Rank()
const {
return RankImpl(); }
1073 int Corank()
const {
return CorankImpl(); }
1078 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
1083 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
1085 SemanticsContext &GetSemanticsContext()
const;
1086#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1087 LLVM_DUMP_METHOD
void dump()
const;
1091 const Scope *owner_;
1094 Attrs implicitAttrs_;
1096 Scope *scope_{
nullptr};
1097 std::size_t size_{0};
1098 std::size_t offset_{0};
1102 std::string GetDetailsName()
const;
1103 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
1104 friend llvm::raw_ostream &DumpForUnparse(
1105 llvm::raw_ostream &,
const Symbol &,
bool);
1107 static constexpr int startRecursionDepth{100};
1109 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
1110 inline int RankImpl(
int depth = startRecursionDepth)
const {
1114 return common::visit(
1116 [&](
const SubprogramDetails &sd) {
1117 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
1119 [](
const GenericDetails &) {
1122 [&](
const ProcBindingDetails &x) {
1123 return x.symbol().RankImpl(depth);
1125 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
1126 [&](
const HostAssocDetails &x) {
1127 return x.symbol().RankImpl(depth);
1129 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1130 [&](
const ProcEntityDetails &ped) {
1131 const Symbol *iface{ped.procInterface()};
1132 return iface ? iface->RankImpl(depth) : 0;
1134 [](
const AssocEntityDetails &aed) {
1135 if (
auto assocRank{aed.rank()}) {
1138 }
else if (aed.IsAssumedRank()) {
1141 }
else if (
const auto &expr{aed.expr()}) {
1142 return expr->Rank();
1147 [](
const auto &) {
return 0; },
1151 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1155 return common::visit(
1157 [&](
const SubprogramDetails &sd) {
1158 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1160 [](
const GenericDetails &) {
return 0; },
1161 [&](
const ProcEntityDetails &ped) {
1162 const Symbol *iface{ped.procInterface()};
1163 return iface ? iface->CorankImpl(depth) : 0;
1165 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1166 [&](
const HostAssocDetails &x) {
1167 return x.symbol().CorankImpl(depth);
1169 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1170 [](
const AssocEntityDetails &aed) {
1171 return aed.expr() ? aed.expr()->Corank() : 0;
1173 [](
const auto &) {
return 0; },
1177 template <std::
size_t>
friend class Symbols;
1178 template <
class, std::
size_t>
friend class std::array;