56 const llvm::omp::ClauseSet &ompRequires()
const {
return ompRequires_; }
57 void set_ompRequires(llvm::omp::ClauseSet 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::ClauseSet &ompDeclTarget()
const {
return ompDeclTarget_; }
68 void set_ompDeclTarget(llvm::omp::ClauseSet 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::ClauseSet &ompGroupprivate()
const {
80 return ompGroupprivate_;
82 void set_ompGroupprivate(llvm::omp::ClauseSet clauses) {
83 ompGroupprivate_ = clauses;
86 const std::optional<common::OmpDeviceType> &
87 ompGroupprivateDeviceType()
const {
88 return ompGroupprivateDeviceType_;
90 void set_ompGroupprivate(common::OmpDeviceType device) {
91 ompGroupprivateDeviceType_ = device;
96 void printClauseSet(llvm::raw_ostream &os,
97 const llvm::omp::ClauseSet &clauses, llvm::omp::Directive dir,
99 friend llvm::raw_ostream &operator<<(
102 void set_version(
unsigned version) { version_ = version; }
110 llvm::omp::ClauseSet ompRequires_;
113 std::optional<common::OmpMemoryOrderType> ompAtomicDefaultMemOrder_;
116 llvm::omp::ClauseSet ompDeclTarget_;
119 std::optional<common::OmpDeviceType> ompDeclTargetDeviceType_;
121 llvm::omp::ClauseSet ompGroupprivate_;
124 std::optional<common::OmpDeviceType> ompGroupprivateDeviceType_;
176class OpenACCRoutineDeviceTypeInfo {
178 explicit OpenACCRoutineDeviceTypeInfo(
179 Fortran::common::OpenACCDeviceType dType)
180 : deviceType_{dType} {}
181 bool isSeq()
const {
return isSeq_; }
182 void set_isSeq(
bool value =
true) { isSeq_ = value; }
183 bool isVector()
const {
return isVector_; }
184 void set_isVector(
bool value =
true) { isVector_ = value; }
185 bool isWorker()
const {
return isWorker_; }
186 void set_isWorker(
bool value =
true) { isWorker_ = value; }
187 bool isGang()
const {
return isGang_; }
188 void set_isGang(
bool value =
true) { isGang_ = value; }
189 unsigned gangDim()
const {
return gangDim_; }
190 void set_gangDim(
unsigned value) { gangDim_ = value; }
191 const std::variant<std::string, SymbolRef> *bindName()
const {
192 return bindName_.has_value() ? &*bindName_ :
nullptr;
194 const std::optional<std::variant<std::string, SymbolRef>> &
195 bindNameOpt()
const {
198 void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
199 void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
201 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
203 friend llvm::raw_ostream &operator<<(
204 llvm::raw_ostream &,
const OpenACCRoutineDeviceTypeInfo &);
208 bool isVector_{
false};
209 bool isWorker_{
false};
211 unsigned gangDim_{0};
214 std::optional<std::variant<std::string, SymbolRef>> bindName_;
215 Fortran::common::OpenACCDeviceType deviceType_{
216 Fortran::common::OpenACCDeviceType::None};
257 bool isFunction()
const {
return result_ !=
nullptr; }
258 bool isInterface()
const {
return isInterface_; }
259 void set_isInterface(
bool value =
true) { isInterface_ = value; }
260 bool isDummy()
const {
return isDummy_; }
261 void set_isDummy(
bool value =
true) { isDummy_ = value; }
262 Scope *entryScope() {
return entryScope_; }
263 const Scope *entryScope()
const {
return entryScope_; }
264 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
265 const Symbol &result()
const {
269 void set_result(
Symbol &result) {
273 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
274 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
275 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
276 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
277 void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
278 Symbol *moduleInterface() {
return moduleInterface_; }
279 const Symbol *moduleInterface()
const {
return moduleInterface_; }
280 void set_moduleInterface(
Symbol &);
281 void ReplaceResult(
Symbol &result) {
282 CHECK(result_ !=
nullptr);
285 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
286 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
287 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
288 return cudaSubprogramAttrs_;
290 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
291 cudaSubprogramAttrs_ = csas;
293 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
294 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
295 return cudaLaunchBounds_;
297 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
298 cudaLaunchBounds_ = std::move(x);
300 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
301 const std::vector<std::int64_t> &cudaClusterDims()
const {
302 return cudaClusterDims_;
304 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
305 cudaClusterDims_ = std::move(x);
307 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
308 return openACCRoutineInfos_;
311 openACCRoutineInfos_.push_back(info);
314 const std::vector<OmpDeclareVariantEntry> &ompDeclareVariants()
const {
315 return ompDeclareVariants_;
318 ompDeclareVariants_.push_back(std::move(entry));
322 bool isInterface_{
false};
323 bool isDummy_{
false};
324 std::vector<Symbol *> dummyArgs_;
326 Scope *entryScope_{
nullptr};
327 MaybeExpr stmtFunction_;
331 Symbol *moduleInterface_{
nullptr};
332 bool defaultIgnoreTKR_{
false};
334 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
336 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
338 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
339 std::vector<OmpDeclareVariantEntry> ompDeclareVariants_;
341 friend llvm::raw_ostream &operator<<(
433 explicit ObjectEntityDetails(EntityDetails &&);
434 ObjectEntityDetails(
const ObjectEntityDetails &) =
default;
435 ObjectEntityDetails(ObjectEntityDetails &&) =
default;
436 ObjectEntityDetails &operator=(
const ObjectEntityDetails &) =
default;
437 ObjectEntityDetails(
bool isDummy =
false) : EntityDetails(isDummy) {}
438 MaybeExpr &init() {
return init_; }
439 const MaybeExpr &init()
const {
return init_; }
440 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
441 const parser::Expr *unanalyzedPDTComponentInit()
const {
442 return unanalyzedPDTComponentInit_;
444 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
445 unanalyzedPDTComponentInit_ = expr;
448 const ArraySpec &shape()
const {
return shape_; }
449 ArraySpec &coshape() {
return coshape_; }
450 const ArraySpec &coshape()
const {
return coshape_; }
453 const Symbol *commonBlock()
const {
return commonBlock_; }
454 void set_commonBlock(
const Symbol &commonBlock) {
455 commonBlock_ = &commonBlock;
457 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
458 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
459 bool IsArray()
const {
return !shape_.empty(); }
460 bool IsCoarray()
const {
return !coshape_.empty(); }
461 bool IsAssumedShape()
const {
462 return isDummy() && shape_.CanBeAssumedShape();
464 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
465 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
466 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
467 return cudaDataAttr_;
469 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
470 cudaDataAttr_ = attr;
476 void add_droppedBoundToCheck(
Bound &&bound) {
477 droppedBoundsToCheck_.emplace_back(std::move(bound));
479 const std::vector<Bound> &droppedBoundsToCheck()
const {
480 return droppedBoundsToCheck_;
485 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
488 std::vector<Bound> droppedBoundsToCheck_;
489 common::IgnoreTKRSet ignoreTKR_;
490 const Symbol *commonBlock_{
nullptr};
491 std::optional<common::CUDADataAttr> cudaDataAttr_;
492 friend llvm::raw_ostream &operator<<(
493 llvm::raw_ostream &,
const ObjectEntityDetails &);
513class ProcEntityDetails :
public EntityDetails,
517 ProcEntityDetails() =
default;
518 explicit ProcEntityDetails(EntityDetails &&);
519 ProcEntityDetails(
const ProcEntityDetails &) =
default;
520 ProcEntityDetails(ProcEntityDetails &&) =
default;
521 ProcEntityDetails &operator=(
const ProcEntityDetails &) =
default;
523 const Symbol *rawProcInterface()
const {
return rawProcInterface_; }
524 const Symbol *procInterface()
const {
return procInterface_; }
525 void set_procInterfaces(
const Symbol &raw,
const Symbol &resolved) {
526 rawProcInterface_ = &raw;
527 procInterface_ = &resolved;
529 inline bool HasExplicitInterface()
const;
533 std::optional<const Symbol *> init()
const {
return init_; }
534 void set_init(
const Symbol &symbol) { init_ = &symbol; }
535 void set_init(std::nullptr_t) { init_ =
nullptr; }
536 bool isCUDAKernel()
const {
return isCUDAKernel_; }
537 void set_isCUDAKernel(
bool yes =
true) { isCUDAKernel_ = yes; }
538 std::optional<SourceName> usedAsProcedureHere()
const {
539 return usedAsProcedureHere_;
541 void set_usedAsProcedureHere(SourceName here) { usedAsProcedureHere_ = here; }
542 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
543 return openACCRoutineInfos_;
546 openACCRoutineInfos_.push_back(info);
550 const Symbol *rawProcInterface_{
nullptr};
551 const Symbol *procInterface_{
nullptr};
552 std::optional<const Symbol *> init_;
553 bool isCUDAKernel_{
false};
554 std::optional<SourceName> usedAsProcedureHere_;
555 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
556 friend llvm::raw_ostream &operator<<(
557 llvm::raw_ostream &,
const ProcEntityDetails &);
567 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
568 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
569 bool sequence()
const {
return sequence_; }
570 bool isDECStructure()
const {
return isDECStructure_; }
571 bool isEnumerationType()
const {
return isEnumerationType_; }
572 void set_isEnumerationType(
bool x =
true) { isEnumerationType_ = x; }
575 static constexpr char ordinalComponentName[]{
"__ordinal"};
576 int enumeratorCount()
const {
return enumeratorCount_; }
577 void set_enumeratorCount(
int n) { enumeratorCount_ = n; }
578 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
579 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
580 bool isForwardReferenced()
const {
return isForwardReferenced_; }
581 void add_paramNameOrder(
const Symbol &symbol) {
582 paramNameOrder_.push_back(symbol);
584 void add_paramDeclOrder(
const Symbol &symbol) {
585 paramDeclOrder_.push_back(symbol);
587 void add_component(
const Symbol &);
588 void set_sequence(
bool x =
true) { sequence_ = x; }
589 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
590 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
591 const std::list<SourceName> &componentNames()
const {
592 return componentNames_;
594 const std::map<SourceName, const parser::Expr *> &
595 originalKindParameterMap()
const {
596 return originalKindParameterMap_;
598 void add_originalKindParameter(SourceName,
const parser::Expr *);
601 const Symbol *GetParentComponent(
const Scope &)
const;
603 std::optional<SourceName> GetParentComponentName()
const {
604 if (componentNames_.empty()) {
607 return componentNames_.front();
611 const Symbol *GetFinalForRank(
int)
const;
618 SymbolVector paramNameOrder_;
619 SymbolVector paramDeclOrder_;
622 std::list<SourceName> componentNames_;
623 std::map<SourceName, SymbolRef> finals_;
624 bool sequence_{
false};
625 bool isDECStructure_{
false};
626 bool isForwardReferenced_{
false};
627 std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
630 bool isEnumerationType_{
false};
631 int enumeratorCount_{0};
633 friend llvm::raw_ostream &operator<<(
917 CrayPointer, CrayPointee,
931 AccPrivate, AccFirstPrivate, AccShared,
933 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
934 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
940 AccDevice, AccHost, AccSelf,
942 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
944 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
947 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
948 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
950 OmpCopyIn, OmpCopyPrivate,
952 OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
954 OmpReserved, OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned,
955 OmpNontemporal, OmpAllocate, OmpDeclarativeAllocateDirective,
956 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
957 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
958 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
959 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
963 const Scope &owner()
const {
return *owner_; }
964 const SourceName &name()
const {
return name_; }
965 Attrs &attrs() {
return attrs_; }
966 const Attrs &attrs()
const {
return attrs_; }
967 Attrs &implicitAttrs() {
return implicitAttrs_; }
968 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
969 Flags &flags() {
return flags_; }
970 const Flags &flags()
const {
return flags_; }
971 bool test(Flag flag)
const {
return flags_.test(flag); }
972 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
974 Scope *scope() {
return scope_; }
975 const Scope *scope()
const {
return scope_; }
976 void set_scope(Scope *scope) { scope_ = scope; }
977 std::size_t size()
const {
return size_; }
978 void set_size(std::size_t size) { size_ = size; }
979 std::size_t offset()
const {
return offset_; }
980 void set_offset(std::size_t offset) { offset_ = offset; }
982 void ReplaceName(
const SourceName &);
983 static std::string OmpFlagToClauseName(Flag ompFlag);
986 template <
typename D>
bool has()
const {
987 return std::holds_alternative<D>(details_);
991 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
992 template <
typename D>
const D *detailsIf()
const {
993 return std::get_if<D>(&details_);
997 template <
typename D> D &get() {
998 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
1000 template <
typename D>
const D &get()
const {
1001 const auto *p{detailsIf<D>()};
1006 Details &details() {
return details_; }
1007 const Details &details()
const {
return details_; }
1010 void set_details(Details &&);
1013 bool CanReplaceDetails(
const Details &details)
const;
1016 inline Symbol &GetUltimate();
1017 inline const Symbol &GetUltimate()
const;
1019 inline DeclTypeSpec *GetType();
1020 inline const DeclTypeSpec *GetType()
const;
1021 void SetType(
const DeclTypeSpec &);
1023 const std::string *GetBindName()
const;
1024 void SetBindName(std::string &&);
1025 bool GetIsExplicitBindName()
const;
1026 void SetIsExplicitBindName(
bool);
1027 void SetIsCDefined(
bool);
1028 bool IsFuncResult()
const;
1029 bool IsObjectArray()
const;
1030 const ArraySpec *GetShape()
const;
1031 bool IsSubprogram()
const;
1032 bool IsFromModFile()
const;
1033 bool HasExplicitInterface()
const {
1034 return common::visit(
1036 [](
const SubprogramDetails &) {
return true; },
1037 [](
const SubprogramNameDetails &) {
return true; },
1038 [&](
const ProcEntityDetails &x) {
1039 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
1041 [](
const ProcBindingDetails &x) {
1042 return x.symbol().HasExplicitInterface();
1044 [](
const UseDetails &x) {
1045 return x.symbol().HasExplicitInterface();
1047 [](
const HostAssocDetails &x) {
1048 return x.symbol().HasExplicitInterface();
1050 [](
const GenericDetails &x) {
1051 return x.specific() && x.specific()->HasExplicitInterface();
1053 [](
const auto &) {
return false; },
1057 bool HasLocalLocality()
const {
1058 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
1061 bool operator==(
const Symbol &that)
const {
return this == &that; }
1062 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
1064 int Rank()
const {
return RankImpl(); }
1065 int Corank()
const {
return CorankImpl(); }
1070 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
1075 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
1077 SemanticsContext &GetSemanticsContext()
const;
1078#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1079 LLVM_DUMP_METHOD
void dump()
const;
1083 const Scope *owner_;
1086 Attrs implicitAttrs_;
1088 Scope *scope_{
nullptr};
1089 std::size_t size_{0};
1090 std::size_t offset_{0};
1094 std::string GetDetailsName()
const;
1095 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
1096 friend llvm::raw_ostream &DumpForUnparse(
1097 llvm::raw_ostream &,
const Symbol &,
bool);
1099 static constexpr int startRecursionDepth{100};
1101 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
1102 inline int RankImpl(
int depth = startRecursionDepth)
const {
1106 return common::visit(
1108 [&](
const SubprogramDetails &sd) {
1109 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
1111 [](
const GenericDetails &) {
1114 [&](
const ProcBindingDetails &x) {
1115 return x.symbol().RankImpl(depth);
1117 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
1118 [&](
const HostAssocDetails &x) {
1119 return x.symbol().RankImpl(depth);
1121 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1122 [&](
const ProcEntityDetails &ped) {
1123 const Symbol *iface{ped.procInterface()};
1124 return iface ? iface->RankImpl(depth) : 0;
1126 [](
const AssocEntityDetails &aed) {
1127 if (
auto assocRank{aed.rank()}) {
1130 }
else if (aed.IsAssumedRank()) {
1133 }
else if (
const auto &expr{aed.expr()}) {
1134 return expr->Rank();
1139 [](
const auto &) {
return 0; },
1143 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1147 return common::visit(
1149 [&](
const SubprogramDetails &sd) {
1150 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1152 [](
const GenericDetails &) {
return 0; },
1153 [&](
const ProcEntityDetails &ped) {
1154 const Symbol *iface{ped.procInterface()};
1155 return iface ? iface->CorankImpl(depth) : 0;
1157 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1158 [&](
const HostAssocDetails &x) {
1159 return x.symbol().CorankImpl(depth);
1161 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1162 [](
const AssocEntityDetails &aed) {
1163 return aed.expr() ? aed.expr()->Corank() : 0;
1165 [](
const auto &) {
return 0; },
1169 template <std::
size_t>
friend class Symbols;
1170 template <
class, std::
size_t>
friend class std::array;