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;
475 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
478 common::IgnoreTKRSet ignoreTKR_;
479 const Symbol *commonBlock_{
nullptr};
480 std::optional<common::CUDADataAttr> cudaDataAttr_;
481 friend llvm::raw_ostream &operator<<(
482 llvm::raw_ostream &,
const ObjectEntityDetails &);
502class ProcEntityDetails :
public EntityDetails,
506 ProcEntityDetails() =
default;
507 explicit ProcEntityDetails(EntityDetails &&);
508 ProcEntityDetails(
const ProcEntityDetails &) =
default;
509 ProcEntityDetails(ProcEntityDetails &&) =
default;
510 ProcEntityDetails &operator=(
const ProcEntityDetails &) =
default;
512 const Symbol *rawProcInterface()
const {
return rawProcInterface_; }
513 const Symbol *procInterface()
const {
return procInterface_; }
514 void set_procInterfaces(
const Symbol &raw,
const Symbol &resolved) {
515 rawProcInterface_ = &raw;
516 procInterface_ = &resolved;
518 inline bool HasExplicitInterface()
const;
522 std::optional<const Symbol *> init()
const {
return init_; }
523 void set_init(
const Symbol &symbol) { init_ = &symbol; }
524 void set_init(std::nullptr_t) { init_ =
nullptr; }
525 bool isCUDAKernel()
const {
return isCUDAKernel_; }
526 void set_isCUDAKernel(
bool yes =
true) { isCUDAKernel_ = yes; }
527 std::optional<SourceName> usedAsProcedureHere()
const {
528 return usedAsProcedureHere_;
530 void set_usedAsProcedureHere(SourceName here) { usedAsProcedureHere_ = here; }
531 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
532 return openACCRoutineInfos_;
535 openACCRoutineInfos_.push_back(info);
539 const Symbol *rawProcInterface_{
nullptr};
540 const Symbol *procInterface_{
nullptr};
541 std::optional<const Symbol *> init_;
542 bool isCUDAKernel_{
false};
543 std::optional<SourceName> usedAsProcedureHere_;
544 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
545 friend llvm::raw_ostream &operator<<(
546 llvm::raw_ostream &,
const ProcEntityDetails &);
556 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
557 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
558 bool sequence()
const {
return sequence_; }
559 bool isDECStructure()
const {
return isDECStructure_; }
560 bool isEnumerationType()
const {
return isEnumerationType_; }
561 void set_isEnumerationType(
bool x =
true) { isEnumerationType_ = x; }
564 static constexpr char ordinalComponentName[]{
"__ordinal"};
565 int enumeratorCount()
const {
return enumeratorCount_; }
566 void set_enumeratorCount(
int n) { enumeratorCount_ = n; }
567 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
568 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
569 bool isForwardReferenced()
const {
return isForwardReferenced_; }
570 void add_paramNameOrder(
const Symbol &symbol) {
571 paramNameOrder_.push_back(symbol);
573 void add_paramDeclOrder(
const Symbol &symbol) {
574 paramDeclOrder_.push_back(symbol);
576 void add_component(
const Symbol &);
577 void set_sequence(
bool x =
true) { sequence_ = x; }
578 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
579 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
580 const std::list<SourceName> &componentNames()
const {
581 return componentNames_;
583 const std::map<SourceName, const parser::Expr *> &
584 originalKindParameterMap()
const {
585 return originalKindParameterMap_;
587 void add_originalKindParameter(SourceName,
const parser::Expr *);
590 const Symbol *GetParentComponent(
const Scope &)
const;
592 std::optional<SourceName> GetParentComponentName()
const {
593 if (componentNames_.empty()) {
596 return componentNames_.front();
600 const Symbol *GetFinalForRank(
int)
const;
607 SymbolVector paramNameOrder_;
608 SymbolVector paramDeclOrder_;
611 std::list<SourceName> componentNames_;
612 std::map<SourceName, SymbolRef> finals_;
613 bool sequence_{
false};
614 bool isDECStructure_{
false};
615 bool isForwardReferenced_{
false};
616 std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
619 bool isEnumerationType_{
false};
620 int enumeratorCount_{0};
622 friend llvm::raw_ostream &operator<<(
906 CrayPointer, CrayPointee,
920 AccPrivate, AccFirstPrivate, AccShared,
922 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
923 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
929 AccDevice, AccHost, AccSelf,
931 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
933 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
936 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
937 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
939 OmpCopyIn, OmpCopyPrivate,
941 OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
943 OmpReserved, OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned,
944 OmpNontemporal, OmpAllocate, OmpDeclarativeAllocateDirective,
945 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
946 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
947 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
948 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
952 const Scope &owner()
const {
return *owner_; }
953 const SourceName &name()
const {
return name_; }
954 Attrs &attrs() {
return attrs_; }
955 const Attrs &attrs()
const {
return attrs_; }
956 Attrs &implicitAttrs() {
return implicitAttrs_; }
957 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
958 Flags &flags() {
return flags_; }
959 const Flags &flags()
const {
return flags_; }
960 bool test(Flag flag)
const {
return flags_.test(flag); }
961 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
963 Scope *scope() {
return scope_; }
964 const Scope *scope()
const {
return scope_; }
965 void set_scope(Scope *scope) { scope_ = scope; }
966 std::size_t size()
const {
return size_; }
967 void set_size(std::size_t size) { size_ = size; }
968 std::size_t offset()
const {
return offset_; }
969 void set_offset(std::size_t offset) { offset_ = offset; }
971 void ReplaceName(
const SourceName &);
972 static std::string OmpFlagToClauseName(Flag ompFlag);
975 template <
typename D>
bool has()
const {
976 return std::holds_alternative<D>(details_);
980 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
981 template <
typename D>
const D *detailsIf()
const {
982 return std::get_if<D>(&details_);
986 template <
typename D> D &get() {
987 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
989 template <
typename D>
const D &get()
const {
990 const auto *p{detailsIf<D>()};
995 Details &details() {
return details_; }
996 const Details &details()
const {
return details_; }
999 void set_details(Details &&);
1002 bool CanReplaceDetails(
const Details &details)
const;
1005 inline Symbol &GetUltimate();
1006 inline const Symbol &GetUltimate()
const;
1008 inline DeclTypeSpec *GetType();
1009 inline const DeclTypeSpec *GetType()
const;
1010 void SetType(
const DeclTypeSpec &);
1012 const std::string *GetBindName()
const;
1013 void SetBindName(std::string &&);
1014 bool GetIsExplicitBindName()
const;
1015 void SetIsExplicitBindName(
bool);
1016 void SetIsCDefined(
bool);
1017 bool IsFuncResult()
const;
1018 bool IsObjectArray()
const;
1019 const ArraySpec *GetShape()
const;
1020 bool IsSubprogram()
const;
1021 bool IsFromModFile()
const;
1022 bool HasExplicitInterface()
const {
1023 return common::visit(
1025 [](
const SubprogramDetails &) {
return true; },
1026 [](
const SubprogramNameDetails &) {
return true; },
1027 [&](
const ProcEntityDetails &x) {
1028 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
1030 [](
const ProcBindingDetails &x) {
1031 return x.symbol().HasExplicitInterface();
1033 [](
const UseDetails &x) {
1034 return x.symbol().HasExplicitInterface();
1036 [](
const HostAssocDetails &x) {
1037 return x.symbol().HasExplicitInterface();
1039 [](
const GenericDetails &x) {
1040 return x.specific() && x.specific()->HasExplicitInterface();
1042 [](
const auto &) {
return false; },
1046 bool HasLocalLocality()
const {
1047 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
1050 bool operator==(
const Symbol &that)
const {
return this == &that; }
1051 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
1053 int Rank()
const {
return RankImpl(); }
1054 int Corank()
const {
return CorankImpl(); }
1059 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
1064 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
1066 SemanticsContext &GetSemanticsContext()
const;
1067#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1068 LLVM_DUMP_METHOD
void dump()
const;
1072 const Scope *owner_;
1075 Attrs implicitAttrs_;
1077 Scope *scope_{
nullptr};
1078 std::size_t size_{0};
1079 std::size_t offset_{0};
1083 std::string GetDetailsName()
const;
1084 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
1085 friend llvm::raw_ostream &DumpForUnparse(
1086 llvm::raw_ostream &,
const Symbol &,
bool);
1088 static constexpr int startRecursionDepth{100};
1090 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
1091 inline int RankImpl(
int depth = startRecursionDepth)
const {
1095 return common::visit(
1097 [&](
const SubprogramDetails &sd) {
1098 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
1100 [](
const GenericDetails &) {
1103 [&](
const ProcBindingDetails &x) {
1104 return x.symbol().RankImpl(depth);
1106 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
1107 [&](
const HostAssocDetails &x) {
1108 return x.symbol().RankImpl(depth);
1110 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1111 [&](
const ProcEntityDetails &ped) {
1112 const Symbol *iface{ped.procInterface()};
1113 return iface ? iface->RankImpl(depth) : 0;
1115 [](
const AssocEntityDetails &aed) {
1116 if (
auto assocRank{aed.rank()}) {
1119 }
else if (aed.IsAssumedRank()) {
1122 }
else if (
const auto &expr{aed.expr()}) {
1123 return expr->Rank();
1128 [](
const auto &) {
return 0; },
1132 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1136 return common::visit(
1138 [&](
const SubprogramDetails &sd) {
1139 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1141 [](
const GenericDetails &) {
return 0; },
1142 [&](
const ProcEntityDetails &ped) {
1143 const Symbol *iface{ped.procInterface()};
1144 return iface ? iface->CorankImpl(depth) : 0;
1146 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1147 [&](
const HostAssocDetails &x) {
1148 return x.symbol().CorankImpl(depth);
1150 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1151 [](
const AssocEntityDetails &aed) {
1152 return aed.expr() ? aed.expr()->Corank() : 0;
1154 [](
const auto &) {
return 0; },
1158 template <std::
size_t>
friend class Symbols;
1159 template <
class, std::
size_t>
friend class std::array;