58 const OmpClauseSet &ompRequires()
const {
return ompRequires_; }
59 void set_ompRequires(OmpClauseSet clauses) { ompRequires_ = clauses; }
61 const std::optional<common::OmpMemoryOrderType> &
62 ompAtomicDefaultMemOrder()
const {
63 return ompAtomicDefaultMemOrder_;
65 void set_ompAtomicDefaultMemOrder(common::OmpMemoryOrderType flags) {
66 ompAtomicDefaultMemOrder_ = flags;
69 const OmpClauseSet &ompDeclTarget()
const {
return ompDeclTarget_; }
70 void set_ompDeclTarget(OmpClauseSet clauses) { 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 OmpClauseSet &ompGroupprivate()
const {
return ompGroupprivate_; }
80 void set_ompGroupprivate(OmpClauseSet clauses) { ompGroupprivate_ = clauses; }
82 const std::optional<common::OmpDeviceType> &
83 ompGroupprivateDeviceType()
const {
84 return ompGroupprivateDeviceType_;
86 void set_ompGroupprivate(common::OmpDeviceType device) {
87 ompGroupprivateDeviceType_ = device;
92 void printClauseSet(llvm::raw_ostream &os,
const OmpClauseSet &clauses,
93 llvm::omp::Directive dir,
95 friend llvm::raw_ostream &operator<<(
98 void set_version(
unsigned version) { version_ = version; }
106 OmpClauseSet ompRequires_;
109 std::optional<common::OmpMemoryOrderType> ompAtomicDefaultMemOrder_;
112 OmpClauseSet ompDeclTarget_;
115 std::optional<common::OmpDeviceType> ompDeclTargetDeviceType_;
117 OmpClauseSet ompGroupprivate_;
120 std::optional<common::OmpDeviceType> ompGroupprivateDeviceType_;
172class OpenACCRoutineDeviceTypeInfo {
174 explicit OpenACCRoutineDeviceTypeInfo(
175 Fortran::common::OpenACCDeviceType dType)
176 : deviceType_{dType} {}
177 bool isSeq()
const {
return isSeq_; }
178 void set_isSeq(
bool value =
true) { isSeq_ = value; }
179 bool isVector()
const {
return isVector_; }
180 void set_isVector(
bool value =
true) { isVector_ = value; }
181 bool isWorker()
const {
return isWorker_; }
182 void set_isWorker(
bool value =
true) { isWorker_ = value; }
183 bool isGang()
const {
return isGang_; }
184 void set_isGang(
bool value =
true) { isGang_ = value; }
185 unsigned gangDim()
const {
return gangDim_; }
186 void set_gangDim(
unsigned value) { gangDim_ = value; }
187 const std::variant<std::string, SymbolRef> *bindName()
const {
188 return bindName_.has_value() ? &*bindName_ :
nullptr;
190 const std::optional<std::variant<std::string, SymbolRef>> &
191 bindNameOpt()
const {
194 void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
195 void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
197 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
199 friend llvm::raw_ostream &operator<<(
200 llvm::raw_ostream &,
const OpenACCRoutineDeviceTypeInfo &);
204 bool isVector_{
false};
205 bool isWorker_{
false};
207 unsigned gangDim_{0};
210 std::optional<std::variant<std::string, SymbolRef>> bindName_;
211 Fortran::common::OpenACCDeviceType deviceType_{
212 Fortran::common::OpenACCDeviceType::None};
253 bool isFunction()
const {
return result_ !=
nullptr; }
254 bool isInterface()
const {
return isInterface_; }
255 void set_isInterface(
bool value =
true) { isInterface_ = value; }
256 bool isDummy()
const {
return isDummy_; }
257 void set_isDummy(
bool value =
true) { isDummy_ = value; }
258 Scope *entryScope() {
return entryScope_; }
259 const Scope *entryScope()
const {
return entryScope_; }
260 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
261 const Symbol &result()
const {
265 void set_result(
Symbol &result) {
269 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
270 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
271 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
272 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
273 void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
274 Symbol *moduleInterface() {
return moduleInterface_; }
275 const Symbol *moduleInterface()
const {
return moduleInterface_; }
276 void set_moduleInterface(
Symbol &);
277 void ReplaceResult(
Symbol &result) {
278 CHECK(result_ !=
nullptr);
281 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
282 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
283 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
284 return cudaSubprogramAttrs_;
286 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
287 cudaSubprogramAttrs_ = csas;
289 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
290 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
291 return cudaLaunchBounds_;
293 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
294 cudaLaunchBounds_ = std::move(x);
296 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
297 const std::vector<std::int64_t> &cudaClusterDims()
const {
298 return cudaClusterDims_;
300 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
301 cudaClusterDims_ = std::move(x);
303 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
304 return openACCRoutineInfos_;
307 openACCRoutineInfos_.push_back(info);
311 bool isInterface_{
false};
312 bool isDummy_{
false};
313 std::vector<Symbol *> dummyArgs_;
315 Scope *entryScope_{
nullptr};
316 MaybeExpr stmtFunction_;
320 Symbol *moduleInterface_{
nullptr};
321 bool defaultIgnoreTKR_{
false};
323 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
325 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
327 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
329 friend llvm::raw_ostream &operator<<(
421 explicit ObjectEntityDetails(EntityDetails &&);
422 ObjectEntityDetails(
const ObjectEntityDetails &) =
default;
423 ObjectEntityDetails(ObjectEntityDetails &&) =
default;
424 ObjectEntityDetails &operator=(
const ObjectEntityDetails &) =
default;
425 ObjectEntityDetails(
bool isDummy =
false) : EntityDetails(isDummy) {}
426 MaybeExpr &init() {
return init_; }
427 const MaybeExpr &init()
const {
return init_; }
428 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
429 const parser::Expr *unanalyzedPDTComponentInit()
const {
430 return unanalyzedPDTComponentInit_;
432 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
433 unanalyzedPDTComponentInit_ = expr;
436 const ArraySpec &shape()
const {
return shape_; }
437 ArraySpec &coshape() {
return coshape_; }
438 const ArraySpec &coshape()
const {
return coshape_; }
441 const Symbol *commonBlock()
const {
return commonBlock_; }
442 void set_commonBlock(
const Symbol &commonBlock) {
443 commonBlock_ = &commonBlock;
445 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
446 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
447 bool IsArray()
const {
return !shape_.empty(); }
448 bool IsCoarray()
const {
return !coshape_.empty(); }
449 bool IsAssumedShape()
const {
450 return isDummy() && shape_.CanBeAssumedShape();
452 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
453 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
454 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
455 return cudaDataAttr_;
457 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
458 cudaDataAttr_ = attr;
463 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
466 common::IgnoreTKRSet ignoreTKR_;
467 const Symbol *commonBlock_{
nullptr};
468 std::optional<common::CUDADataAttr> cudaDataAttr_;
469 friend llvm::raw_ostream &operator<<(
470 llvm::raw_ostream &,
const ObjectEntityDetails &);
490class ProcEntityDetails :
public EntityDetails,
494 ProcEntityDetails() =
default;
495 explicit ProcEntityDetails(EntityDetails &&);
496 ProcEntityDetails(
const ProcEntityDetails &) =
default;
497 ProcEntityDetails(ProcEntityDetails &&) =
default;
498 ProcEntityDetails &operator=(
const ProcEntityDetails &) =
default;
500 const Symbol *rawProcInterface()
const {
return rawProcInterface_; }
501 const Symbol *procInterface()
const {
return procInterface_; }
502 void set_procInterfaces(
const Symbol &raw,
const Symbol &resolved) {
503 rawProcInterface_ = &raw;
504 procInterface_ = &resolved;
506 inline bool HasExplicitInterface()
const;
510 std::optional<const Symbol *> init()
const {
return init_; }
511 void set_init(
const Symbol &symbol) { init_ = &symbol; }
512 void set_init(std::nullptr_t) { init_ =
nullptr; }
513 bool isCUDAKernel()
const {
return isCUDAKernel_; }
514 void set_isCUDAKernel(
bool yes =
true) { isCUDAKernel_ = yes; }
515 std::optional<SourceName> usedAsProcedureHere()
const {
516 return usedAsProcedureHere_;
518 void set_usedAsProcedureHere(SourceName here) { usedAsProcedureHere_ = here; }
519 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
520 return openACCRoutineInfos_;
523 openACCRoutineInfos_.push_back(info);
527 const Symbol *rawProcInterface_{
nullptr};
528 const Symbol *procInterface_{
nullptr};
529 std::optional<const Symbol *> init_;
530 bool isCUDAKernel_{
false};
531 std::optional<SourceName> usedAsProcedureHere_;
532 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
533 friend llvm::raw_ostream &operator<<(
534 llvm::raw_ostream &,
const ProcEntityDetails &);
544 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
545 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
546 bool sequence()
const {
return sequence_; }
547 bool isDECStructure()
const {
return isDECStructure_; }
548 bool isEnumerationType()
const {
return isEnumerationType_; }
549 void set_isEnumerationType(
bool x =
true) { isEnumerationType_ = x; }
550 int enumeratorCount()
const {
return enumeratorCount_; }
551 void set_enumeratorCount(
int n) { enumeratorCount_ = n; }
552 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
553 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
554 bool isForwardReferenced()
const {
return isForwardReferenced_; }
555 void add_paramNameOrder(
const Symbol &symbol) {
556 paramNameOrder_.push_back(symbol);
558 void add_paramDeclOrder(
const Symbol &symbol) {
559 paramDeclOrder_.push_back(symbol);
561 void add_component(
const Symbol &);
562 void set_sequence(
bool x =
true) { sequence_ = x; }
563 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
564 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
565 const std::list<SourceName> &componentNames()
const {
566 return componentNames_;
568 const std::map<SourceName, const parser::Expr *> &
569 originalKindParameterMap()
const {
570 return originalKindParameterMap_;
572 void add_originalKindParameter(SourceName,
const parser::Expr *);
575 const Symbol *GetParentComponent(
const Scope &)
const;
577 std::optional<SourceName> GetParentComponentName()
const {
578 if (componentNames_.empty()) {
581 return componentNames_.front();
585 const Symbol *GetFinalForRank(
int)
const;
592 SymbolVector paramNameOrder_;
593 SymbolVector paramDeclOrder_;
596 std::list<SourceName> componentNames_;
597 std::map<SourceName, SymbolRef> finals_;
598 bool sequence_{
false};
599 bool isDECStructure_{
false};
600 bool isForwardReferenced_{
false};
601 std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
604 bool isEnumerationType_{
false};
605 int enumeratorCount_{0};
607 friend llvm::raw_ostream &operator<<(
891 CrayPointer, CrayPointee,
905 AccPrivate, AccFirstPrivate, AccShared,
907 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
908 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
914 AccDevice, AccHost, AccSelf,
916 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
918 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
921 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
922 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
924 OmpCopyIn, OmpCopyPrivate,
926 OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
928 OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
929 OmpAllocate, OmpDeclarativeAllocateDirective,
930 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
931 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
932 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
933 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
937 const Scope &owner()
const {
return *owner_; }
938 const SourceName &name()
const {
return name_; }
939 Attrs &attrs() {
return attrs_; }
940 const Attrs &attrs()
const {
return attrs_; }
941 Attrs &implicitAttrs() {
return implicitAttrs_; }
942 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
943 Flags &flags() {
return flags_; }
944 const Flags &flags()
const {
return flags_; }
945 bool test(Flag flag)
const {
return flags_.test(flag); }
946 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
948 Scope *scope() {
return scope_; }
949 const Scope *scope()
const {
return scope_; }
950 void set_scope(Scope *scope) { scope_ = scope; }
951 std::size_t size()
const {
return size_; }
952 void set_size(std::size_t size) { size_ = size; }
953 std::size_t offset()
const {
return offset_; }
954 void set_offset(std::size_t offset) { offset_ = offset; }
956 void ReplaceName(
const SourceName &);
957 static std::string OmpFlagToClauseName(Flag ompFlag);
960 template <
typename D>
bool has()
const {
961 return std::holds_alternative<D>(details_);
965 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
966 template <
typename D>
const D *detailsIf()
const {
967 return std::get_if<D>(&details_);
971 template <
typename D> D &get() {
972 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
974 template <
typename D>
const D &get()
const {
975 const auto *p{detailsIf<D>()};
980 Details &details() {
return details_; }
981 const Details &details()
const {
return details_; }
984 void set_details(Details &&);
987 bool CanReplaceDetails(
const Details &details)
const;
990 inline Symbol &GetUltimate();
991 inline const Symbol &GetUltimate()
const;
993 inline DeclTypeSpec *GetType();
994 inline const DeclTypeSpec *GetType()
const;
995 void SetType(
const DeclTypeSpec &);
997 const std::string *GetBindName()
const;
998 void SetBindName(std::string &&);
999 bool GetIsExplicitBindName()
const;
1000 void SetIsExplicitBindName(
bool);
1001 void SetIsCDefined(
bool);
1002 bool IsFuncResult()
const;
1003 bool IsObjectArray()
const;
1004 const ArraySpec *GetShape()
const;
1005 bool IsSubprogram()
const;
1006 bool IsFromModFile()
const;
1007 bool HasExplicitInterface()
const {
1008 return common::visit(
1010 [](
const SubprogramDetails &) {
return true; },
1011 [](
const SubprogramNameDetails &) {
return true; },
1012 [&](
const ProcEntityDetails &x) {
1013 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
1015 [](
const ProcBindingDetails &x) {
1016 return x.symbol().HasExplicitInterface();
1018 [](
const UseDetails &x) {
1019 return x.symbol().HasExplicitInterface();
1021 [](
const HostAssocDetails &x) {
1022 return x.symbol().HasExplicitInterface();
1024 [](
const GenericDetails &x) {
1025 return x.specific() && x.specific()->HasExplicitInterface();
1027 [](
const auto &) {
return false; },
1031 bool HasLocalLocality()
const {
1032 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
1035 bool operator==(
const Symbol &that)
const {
return this == &that; }
1036 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
1038 int Rank()
const {
return RankImpl(); }
1039 int Corank()
const {
return CorankImpl(); }
1044 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
1049 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
1051 SemanticsContext &GetSemanticsContext()
const;
1052#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1053 LLVM_DUMP_METHOD
void dump()
const;
1057 const Scope *owner_;
1060 Attrs implicitAttrs_;
1062 Scope *scope_{
nullptr};
1063 std::size_t size_{0};
1064 std::size_t offset_{0};
1068 std::string GetDetailsName()
const;
1069 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
1070 friend llvm::raw_ostream &DumpForUnparse(
1071 llvm::raw_ostream &,
const Symbol &,
bool);
1073 static constexpr int startRecursionDepth{100};
1075 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
1076 inline int RankImpl(
int depth = startRecursionDepth)
const {
1080 return common::visit(
1082 [&](
const SubprogramDetails &sd) {
1083 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
1085 [](
const GenericDetails &) {
1088 [&](
const ProcBindingDetails &x) {
1089 return x.symbol().RankImpl(depth);
1091 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
1092 [&](
const HostAssocDetails &x) {
1093 return x.symbol().RankImpl(depth);
1095 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1096 [&](
const ProcEntityDetails &ped) {
1097 const Symbol *iface{ped.procInterface()};
1098 return iface ? iface->RankImpl(depth) : 0;
1100 [](
const AssocEntityDetails &aed) {
1101 if (
auto assocRank{aed.rank()}) {
1104 }
else if (aed.IsAssumedRank()) {
1107 }
else if (
const auto &expr{aed.expr()}) {
1108 return expr->Rank();
1113 [](
const auto &) {
return 0; },
1117 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1121 return common::visit(
1123 [&](
const SubprogramDetails &sd) {
1124 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1126 [](
const GenericDetails &) {
return 0; },
1127 [&](
const ProcEntityDetails &ped) {
1128 const Symbol *iface{ped.procInterface()};
1129 return iface ? iface->CorankImpl(depth) : 0;
1131 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1132 [&](
const HostAssocDetails &x) {
1133 return x.symbol().CorankImpl(depth);
1135 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1136 [](
const AssocEntityDetails &aed) {
1137 return aed.expr() ? aed.expr()->Corank() : 0;
1139 [](
const auto &) {
return 0; },
1143 template <std::
size_t>
friend class Symbols;
1144 template <
class, std::
size_t>
friend class std::array;