54 using OmpAtomicOrderType = common::OmpMemoryOrderType;
57 ENUM_CLASS(RequiresFlag, ReverseOffload, UnifiedAddress, UnifiedSharedMemory,
61 bool has_ompRequires()
const {
return ompRequires_.has_value(); }
62 const RequiresFlags *ompRequires()
const {
63 return ompRequires_ ? &*ompRequires_ :
nullptr;
65 void set_ompRequires(RequiresFlags flags) { ompRequires_ = flags; }
67 bool has_ompAtomicDefaultMemOrder()
const {
68 return ompAtomicDefaultMemOrder_.has_value();
70 const OmpAtomicOrderType *ompAtomicDefaultMemOrder()
const {
71 return ompAtomicDefaultMemOrder_ ? &*ompAtomicDefaultMemOrder_ :
nullptr;
73 void set_ompAtomicDefaultMemOrder(OmpAtomicOrderType flags) {
74 ompAtomicDefaultMemOrder_ = flags;
78 std::optional<RequiresFlags> ompRequires_;
79 std::optional<OmpAtomicOrderType> ompAtomicDefaultMemOrder_;
131class OpenACCRoutineDeviceTypeInfo {
133 explicit OpenACCRoutineDeviceTypeInfo(
134 Fortran::common::OpenACCDeviceType dType)
135 : deviceType_{dType} {}
136 bool isSeq()
const {
return isSeq_; }
137 void set_isSeq(
bool value =
true) { isSeq_ = value; }
138 bool isVector()
const {
return isVector_; }
139 void set_isVector(
bool value =
true) { isVector_ = value; }
140 bool isWorker()
const {
return isWorker_; }
141 void set_isWorker(
bool value =
true) { isWorker_ = value; }
142 bool isGang()
const {
return isGang_; }
143 void set_isGang(
bool value =
true) { isGang_ = value; }
144 unsigned gangDim()
const {
return gangDim_; }
145 void set_gangDim(
unsigned value) { gangDim_ = value; }
146 const std::variant<std::string, SymbolRef> *bindName()
const {
147 return bindName_.has_value() ? &*bindName_ :
nullptr;
149 const std::optional<std::variant<std::string, SymbolRef>> &
150 bindNameOpt()
const {
153 void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
154 void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
156 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
158 friend llvm::raw_ostream &operator<<(
159 llvm::raw_ostream &,
const OpenACCRoutineDeviceTypeInfo &);
163 bool isVector_{
false};
164 bool isWorker_{
false};
166 unsigned gangDim_{0};
169 std::optional<std::variant<std::string, SymbolRef>> bindName_;
170 Fortran::common::OpenACCDeviceType deviceType_{
171 Fortran::common::OpenACCDeviceType::None};
212 bool isFunction()
const {
return result_ !=
nullptr; }
213 bool isInterface()
const {
return isInterface_; }
214 void set_isInterface(
bool value =
true) { isInterface_ = value; }
215 bool isDummy()
const {
return isDummy_; }
216 void set_isDummy(
bool value =
true) { isDummy_ = value; }
217 Scope *entryScope() {
return entryScope_; }
218 const Scope *entryScope()
const {
return entryScope_; }
219 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
220 const Symbol &result()
const {
224 void set_result(
Symbol &result) {
228 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
229 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
230 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
231 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
232 void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
233 Symbol *moduleInterface() {
return moduleInterface_; }
234 const Symbol *moduleInterface()
const {
return moduleInterface_; }
235 void set_moduleInterface(
Symbol &);
236 void ReplaceResult(
Symbol &result) {
237 CHECK(result_ !=
nullptr);
240 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
241 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
242 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
243 return cudaSubprogramAttrs_;
245 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
246 cudaSubprogramAttrs_ = csas;
248 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
249 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
250 return cudaLaunchBounds_;
252 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
253 cudaLaunchBounds_ = std::move(x);
255 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
256 const std::vector<std::int64_t> &cudaClusterDims()
const {
257 return cudaClusterDims_;
259 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
260 cudaClusterDims_ = std::move(x);
262 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
263 return openACCRoutineInfos_;
266 openACCRoutineInfos_.push_back(info);
270 bool isInterface_{
false};
271 bool isDummy_{
false};
272 std::vector<Symbol *> dummyArgs_;
274 Scope *entryScope_{
nullptr};
275 MaybeExpr stmtFunction_;
279 Symbol *moduleInterface_{
nullptr};
280 bool defaultIgnoreTKR_{
false};
282 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
284 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
286 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
288 friend llvm::raw_ostream &operator<<(
378class ObjectEntityDetails :
public EntityDetails {
380 explicit ObjectEntityDetails(EntityDetails &&);
381 ObjectEntityDetails(
const ObjectEntityDetails &) =
default;
382 ObjectEntityDetails(ObjectEntityDetails &&) =
default;
383 ObjectEntityDetails &operator=(
const ObjectEntityDetails &) =
default;
384 ObjectEntityDetails(
bool isDummy =
false) : EntityDetails(isDummy) {}
385 MaybeExpr &init() {
return init_; }
386 const MaybeExpr &init()
const {
return init_; }
387 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
388 const parser::Expr *unanalyzedPDTComponentInit()
const {
389 return unanalyzedPDTComponentInit_;
391 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
392 unanalyzedPDTComponentInit_ = expr;
395 const ArraySpec &shape()
const {
return shape_; }
396 ArraySpec &coshape() {
return coshape_; }
397 const ArraySpec &coshape()
const {
return coshape_; }
400 const Symbol *commonBlock()
const {
return commonBlock_; }
401 void set_commonBlock(
const Symbol &commonBlock) {
402 commonBlock_ = &commonBlock;
404 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
405 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
406 bool IsArray()
const {
return !shape_.empty(); }
407 bool IsCoarray()
const {
return !coshape_.empty(); }
408 bool IsAssumedShape()
const {
409 return isDummy() && shape_.CanBeAssumedShape();
411 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
412 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
413 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
414 return cudaDataAttr_;
416 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
417 cudaDataAttr_ = attr;
422 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
425 common::IgnoreTKRSet ignoreTKR_;
426 const Symbol *commonBlock_{
nullptr};
427 std::optional<common::CUDADataAttr> cudaDataAttr_;
428 friend llvm::raw_ostream &operator<<(
429 llvm::raw_ostream &,
const ObjectEntityDetails &);
494 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
495 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
496 bool sequence()
const {
return sequence_; }
497 bool isDECStructure()
const {
return isDECStructure_; }
498 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
499 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
500 bool isForwardReferenced()
const {
return isForwardReferenced_; }
501 void add_paramNameOrder(
const Symbol &symbol) {
502 paramNameOrder_.push_back(symbol);
504 void add_paramDeclOrder(
const Symbol &symbol) {
505 paramDeclOrder_.push_back(symbol);
507 void add_component(
const Symbol &);
508 void set_sequence(
bool x =
true) { sequence_ = x; }
509 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
510 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
511 const std::list<SourceName> &componentNames()
const {
512 return componentNames_;
516 const Symbol *GetParentComponent(
const Scope &)
const;
518 std::optional<SourceName> GetParentComponentName()
const {
519 if (componentNames_.empty()) {
522 return componentNames_.front();
526 const Symbol *GetFinalForRank(
int)
const;
533 SymbolVector paramNameOrder_;
534 SymbolVector paramDeclOrder_;
537 std::list<SourceName> componentNames_;
538 std::map<SourceName, SymbolRef> finals_;
539 bool sequence_{
false};
540 bool isDECStructure_{
false};
541 bool isForwardReferenced_{
false};
542 friend llvm::raw_ostream &operator<<(
788 CrayPointer, CrayPointee,
802 AccPrivate, AccFirstPrivate, AccShared,
804 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
805 AccPresent, AccLink, AccDeviceResident, AccDevicePtr,
809 AccDevice, AccHost, AccSelf,
811 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
813 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
816 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
817 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
819 OmpCopyIn, OmpCopyPrivate,
821 OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
822 OmpAllocate, OmpDeclarativeAllocateDirective,
823 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
824 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
825 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
826 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
830 const Scope &owner()
const {
return *owner_; }
831 const SourceName &name()
const {
return name_; }
832 Attrs &attrs() {
return attrs_; }
833 const Attrs &attrs()
const {
return attrs_; }
834 Attrs &implicitAttrs() {
return implicitAttrs_; }
835 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
836 Flags &flags() {
return flags_; }
837 const Flags &flags()
const {
return flags_; }
838 bool test(Flag flag)
const {
return flags_.test(flag); }
839 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
841 Scope *scope() {
return scope_; }
842 const Scope *scope()
const {
return scope_; }
843 void set_scope(Scope *scope) { scope_ = scope; }
844 std::size_t size()
const {
return size_; }
845 void set_size(std::size_t size) { size_ = size; }
846 std::size_t offset()
const {
return offset_; }
847 void set_offset(std::size_t offset) { offset_ = offset; }
849 void ReplaceName(
const SourceName &);
850 static std::string OmpFlagToClauseName(Flag ompFlag);
853 template <
typename D>
bool has()
const {
854 return std::holds_alternative<D>(details_);
858 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
859 template <
typename D>
const D *detailsIf()
const {
860 return std::get_if<D>(&details_);
864 template <
typename D> D &get() {
865 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
867 template <
typename D>
const D &get()
const {
868 const auto *p{detailsIf<D>()};
873 Details &details() {
return details_; }
874 const Details &details()
const {
return details_; }
877 void set_details(Details &&);
880 bool CanReplaceDetails(
const Details &details)
const;
883 inline Symbol &GetUltimate();
884 inline const Symbol &GetUltimate()
const;
886 inline DeclTypeSpec *GetType();
887 inline const DeclTypeSpec *GetType()
const;
888 void SetType(
const DeclTypeSpec &);
890 const std::string *GetBindName()
const;
891 void SetBindName(std::string &&);
892 bool GetIsExplicitBindName()
const;
893 void SetIsExplicitBindName(
bool);
894 void SetIsCDefined(
bool);
895 bool IsFuncResult()
const;
896 bool IsObjectArray()
const;
897 const ArraySpec *GetShape()
const;
898 bool IsSubprogram()
const;
899 bool IsFromModFile()
const;
900 bool HasExplicitInterface()
const {
901 return common::visit(
903 [](
const SubprogramDetails &) {
return true; },
904 [](
const SubprogramNameDetails &) {
return true; },
905 [&](
const ProcEntityDetails &x) {
906 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
908 [](
const ProcBindingDetails &x) {
909 return x.symbol().HasExplicitInterface();
911 [](
const UseDetails &x) {
912 return x.symbol().HasExplicitInterface();
914 [](
const HostAssocDetails &x) {
915 return x.symbol().HasExplicitInterface();
917 [](
const GenericDetails &x) {
918 return x.specific() && x.specific()->HasExplicitInterface();
920 [](
const auto &) {
return false; },
924 bool HasLocalLocality()
const {
925 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
928 bool operator==(
const Symbol &that)
const {
return this == &that; }
929 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
931 int Rank()
const {
return RankImpl(); }
932 int Corank()
const {
return CorankImpl(); }
937 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
942 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
944 SemanticsContext &GetSemanticsContext()
const;
945#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
946 LLVM_DUMP_METHOD
void dump()
const;
953 Attrs implicitAttrs_;
955 Scope *scope_{
nullptr};
956 std::size_t size_{0};
957 std::size_t offset_{0};
961 std::string GetDetailsName()
const;
962 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
963 friend llvm::raw_ostream &DumpForUnparse(
964 llvm::raw_ostream &,
const Symbol &,
bool);
966 static constexpr int startRecursionDepth{100};
968 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
969 inline int RankImpl(
int depth = startRecursionDepth)
const {
973 return common::visit(
975 [&](
const SubprogramDetails &sd) {
976 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
978 [](
const GenericDetails &) {
981 [&](
const ProcBindingDetails &x) {
982 return x.symbol().RankImpl(depth);
984 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
985 [&](
const HostAssocDetails &x) {
986 return x.symbol().RankImpl(depth);
988 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
989 [&](
const ProcEntityDetails &ped) {
990 const Symbol *iface{ped.procInterface()};
991 return iface ? iface->RankImpl(depth) : 0;
993 [](
const AssocEntityDetails &aed) {
994 if (
auto assocRank{aed.rank()}) {
997 }
else if (aed.IsAssumedRank()) {
1000 }
else if (
const auto &expr{aed.expr()}) {
1001 return expr->Rank();
1006 [](
const auto &) {
return 0; },
1010 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1014 return common::visit(
1016 [&](
const SubprogramDetails &sd) {
1017 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1019 [](
const GenericDetails &) {
return 0; },
1020 [&](
const ProcEntityDetails &ped) {
1021 const Symbol *iface{ped.procInterface()};
1022 return iface ? iface->CorankImpl(depth) : 0;
1024 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1025 [&](
const HostAssocDetails &x) {
1026 return x.symbol().CorankImpl(depth);
1028 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1029 [](
const AssocEntityDetails &aed) {
1030 return aed.expr() ? aed.expr()->Corank() : 0;
1032 [](
const auto &) {
return 0; },
1036 template <std::
size_t>
friend class Symbols;
1037 template <
class, std::
size_t>
friend class std::array;