53 using OmpAtomicOrderType = common::OmpMemoryOrderType;
56 ENUM_CLASS(RequiresFlag, ReverseOffload, UnifiedAddress, UnifiedSharedMemory,
60 bool has_ompRequires()
const {
return ompRequires_.has_value(); }
61 const RequiresFlags *ompRequires()
const {
62 return ompRequires_ ? &*ompRequires_ :
nullptr;
64 void set_ompRequires(RequiresFlags flags) { ompRequires_ = flags; }
66 bool has_ompAtomicDefaultMemOrder()
const {
67 return ompAtomicDefaultMemOrder_.has_value();
69 const OmpAtomicOrderType *ompAtomicDefaultMemOrder()
const {
70 return ompAtomicDefaultMemOrder_ ? &*ompAtomicDefaultMemOrder_ :
nullptr;
72 void set_ompAtomicDefaultMemOrder(OmpAtomicOrderType flags) {
73 ompAtomicDefaultMemOrder_ = flags;
77 std::optional<RequiresFlags> ompRequires_;
78 std::optional<OmpAtomicOrderType> ompAtomicDefaultMemOrder_;
130class OpenACCRoutineDeviceTypeInfo {
132 explicit OpenACCRoutineDeviceTypeInfo(
133 Fortran::common::OpenACCDeviceType dType)
134 : deviceType_{dType} {}
135 bool isSeq()
const {
return isSeq_; }
136 void set_isSeq(
bool value =
true) { isSeq_ = value; }
137 bool isVector()
const {
return isVector_; }
138 void set_isVector(
bool value =
true) { isVector_ = value; }
139 bool isWorker()
const {
return isWorker_; }
140 void set_isWorker(
bool value =
true) { isWorker_ = value; }
141 bool isGang()
const {
return isGang_; }
142 void set_isGang(
bool value =
true) { isGang_ = value; }
143 unsigned gangDim()
const {
return gangDim_; }
144 void set_gangDim(
unsigned value) { gangDim_ = value; }
145 const std::variant<std::string, SymbolRef> *bindName()
const {
146 return bindName_.has_value() ? &*bindName_ :
nullptr;
148 const std::optional<std::variant<std::string, SymbolRef>> &
149 bindNameOpt()
const {
152 void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
153 void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
155 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
157 friend llvm::raw_ostream &operator<<(
158 llvm::raw_ostream &,
const OpenACCRoutineDeviceTypeInfo &);
162 bool isVector_{
false};
163 bool isWorker_{
false};
165 unsigned gangDim_{0};
168 std::optional<std::variant<std::string, SymbolRef>> bindName_;
169 Fortran::common::OpenACCDeviceType deviceType_{
170 Fortran::common::OpenACCDeviceType::None};
211 bool isFunction()
const {
return result_ !=
nullptr; }
212 bool isInterface()
const {
return isInterface_; }
213 void set_isInterface(
bool value =
true) { isInterface_ = value; }
214 bool isDummy()
const {
return isDummy_; }
215 void set_isDummy(
bool value =
true) { isDummy_ = value; }
216 Scope *entryScope() {
return entryScope_; }
217 const Scope *entryScope()
const {
return entryScope_; }
218 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
219 const Symbol &result()
const {
223 void set_result(
Symbol &result) {
227 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
228 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
229 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
230 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
231 void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
232 Symbol *moduleInterface() {
return moduleInterface_; }
233 const Symbol *moduleInterface()
const {
return moduleInterface_; }
234 void set_moduleInterface(
Symbol &);
235 void ReplaceResult(
Symbol &result) {
236 CHECK(result_ !=
nullptr);
239 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
240 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
241 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
242 return cudaSubprogramAttrs_;
244 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
245 cudaSubprogramAttrs_ = csas;
247 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
248 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
249 return cudaLaunchBounds_;
251 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
252 cudaLaunchBounds_ = std::move(x);
254 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
255 const std::vector<std::int64_t> &cudaClusterDims()
const {
256 return cudaClusterDims_;
258 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
259 cudaClusterDims_ = std::move(x);
261 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
262 return openACCRoutineInfos_;
265 openACCRoutineInfos_.push_back(info);
269 bool isInterface_{
false};
270 bool isDummy_{
false};
271 std::vector<Symbol *> dummyArgs_;
273 Scope *entryScope_{
nullptr};
274 MaybeExpr stmtFunction_;
278 Symbol *moduleInterface_{
nullptr};
279 bool defaultIgnoreTKR_{
false};
281 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
283 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
285 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
287 friend llvm::raw_ostream &operator<<(
377class ObjectEntityDetails :
public EntityDetails {
379 explicit ObjectEntityDetails(EntityDetails &&);
380 ObjectEntityDetails(
const ObjectEntityDetails &) =
default;
381 ObjectEntityDetails(ObjectEntityDetails &&) =
default;
382 ObjectEntityDetails &operator=(
const ObjectEntityDetails &) =
default;
383 ObjectEntityDetails(
bool isDummy =
false) : EntityDetails(isDummy) {}
384 MaybeExpr &init() {
return init_; }
385 const MaybeExpr &init()
const {
return init_; }
386 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
387 const parser::Expr *unanalyzedPDTComponentInit()
const {
388 return unanalyzedPDTComponentInit_;
390 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
391 unanalyzedPDTComponentInit_ = expr;
394 const ArraySpec &shape()
const {
return shape_; }
395 ArraySpec &coshape() {
return coshape_; }
396 const ArraySpec &coshape()
const {
return coshape_; }
399 const Symbol *commonBlock()
const {
return commonBlock_; }
400 void set_commonBlock(
const Symbol &commonBlock) {
401 commonBlock_ = &commonBlock;
403 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
404 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
405 bool IsArray()
const {
return !shape_.empty(); }
406 bool IsCoarray()
const {
return !coshape_.empty(); }
407 bool IsAssumedShape()
const {
408 return isDummy() && shape_.CanBeAssumedShape();
410 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
411 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
412 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
413 return cudaDataAttr_;
415 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
416 cudaDataAttr_ = attr;
421 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
424 common::IgnoreTKRSet ignoreTKR_;
425 const Symbol *commonBlock_{
nullptr};
426 std::optional<common::CUDADataAttr> cudaDataAttr_;
427 friend llvm::raw_ostream &operator<<(
428 llvm::raw_ostream &,
const ObjectEntityDetails &);
493 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
494 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
495 bool sequence()
const {
return sequence_; }
496 bool isDECStructure()
const {
return isDECStructure_; }
497 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
498 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
499 bool isForwardReferenced()
const {
return isForwardReferenced_; }
500 void add_paramNameOrder(
const Symbol &symbol) {
501 paramNameOrder_.push_back(symbol);
503 void add_paramDeclOrder(
const Symbol &symbol) {
504 paramDeclOrder_.push_back(symbol);
506 void add_component(
const Symbol &);
507 void set_sequence(
bool x =
true) { sequence_ = x; }
508 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
509 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
510 const std::list<SourceName> &componentNames()
const {
511 return componentNames_;
515 const Symbol *GetParentComponent(
const Scope &)
const;
517 std::optional<SourceName> GetParentComponentName()
const {
518 if (componentNames_.empty()) {
521 return componentNames_.front();
525 const Symbol *GetFinalForRank(
int)
const;
532 SymbolVector paramNameOrder_;
533 SymbolVector paramDeclOrder_;
536 std::list<SourceName> componentNames_;
537 std::map<SourceName, SymbolRef> finals_;
538 bool sequence_{
false};
539 bool isDECStructure_{
false};
540 bool isForwardReferenced_{
false};
541 friend llvm::raw_ostream &operator<<(
791 CrayPointer, CrayPointee,
805 AccPrivate, AccFirstPrivate, AccShared,
807 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
808 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
812 AccDevice, AccHost, AccSelf,
814 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
816 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
819 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
820 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
822 OmpCopyIn, OmpCopyPrivate,
824 OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
825 OmpAllocate, OmpDeclarativeAllocateDirective,
826 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
827 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
828 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
829 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
833 const Scope &owner()
const {
return *owner_; }
834 const SourceName &name()
const {
return name_; }
835 Attrs &attrs() {
return attrs_; }
836 const Attrs &attrs()
const {
return attrs_; }
837 Attrs &implicitAttrs() {
return implicitAttrs_; }
838 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
839 Flags &flags() {
return flags_; }
840 const Flags &flags()
const {
return flags_; }
841 bool test(Flag flag)
const {
return flags_.test(flag); }
842 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
844 Scope *scope() {
return scope_; }
845 const Scope *scope()
const {
return scope_; }
846 void set_scope(Scope *scope) { scope_ = scope; }
847 std::size_t size()
const {
return size_; }
848 void set_size(std::size_t size) { size_ = size; }
849 std::size_t offset()
const {
return offset_; }
850 void set_offset(std::size_t offset) { offset_ = offset; }
852 void ReplaceName(
const SourceName &);
853 static std::string OmpFlagToClauseName(Flag ompFlag);
856 template <
typename D>
bool has()
const {
857 return std::holds_alternative<D>(details_);
861 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
862 template <
typename D>
const D *detailsIf()
const {
863 return std::get_if<D>(&details_);
867 template <
typename D> D &get() {
868 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
870 template <
typename D>
const D &get()
const {
871 const auto *p{detailsIf<D>()};
876 Details &details() {
return details_; }
877 const Details &details()
const {
return details_; }
880 void set_details(Details &&);
883 bool CanReplaceDetails(
const Details &details)
const;
886 inline Symbol &GetUltimate();
887 inline const Symbol &GetUltimate()
const;
889 inline DeclTypeSpec *GetType();
890 inline const DeclTypeSpec *GetType()
const;
891 void SetType(
const DeclTypeSpec &);
893 const std::string *GetBindName()
const;
894 void SetBindName(std::string &&);
895 bool GetIsExplicitBindName()
const;
896 void SetIsExplicitBindName(
bool);
897 void SetIsCDefined(
bool);
898 bool IsFuncResult()
const;
899 bool IsObjectArray()
const;
900 const ArraySpec *GetShape()
const;
901 bool IsSubprogram()
const;
902 bool IsFromModFile()
const;
903 bool HasExplicitInterface()
const {
904 return common::visit(
906 [](
const SubprogramDetails &) {
return true; },
907 [](
const SubprogramNameDetails &) {
return true; },
908 [&](
const ProcEntityDetails &x) {
909 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
911 [](
const ProcBindingDetails &x) {
912 return x.symbol().HasExplicitInterface();
914 [](
const UseDetails &x) {
915 return x.symbol().HasExplicitInterface();
917 [](
const HostAssocDetails &x) {
918 return x.symbol().HasExplicitInterface();
920 [](
const GenericDetails &x) {
921 return x.specific() && x.specific()->HasExplicitInterface();
923 [](
const auto &) {
return false; },
927 bool HasLocalLocality()
const {
928 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
931 bool operator==(
const Symbol &that)
const {
return this == &that; }
932 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
934 int Rank()
const {
return RankImpl(); }
935 int Corank()
const {
return CorankImpl(); }
940 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
945 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
947 SemanticsContext &GetSemanticsContext()
const;
948#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
949 LLVM_DUMP_METHOD
void dump()
const;
956 Attrs implicitAttrs_;
958 Scope *scope_{
nullptr};
959 std::size_t size_{0};
960 std::size_t offset_{0};
964 std::string GetDetailsName()
const;
965 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
966 friend llvm::raw_ostream &DumpForUnparse(
967 llvm::raw_ostream &,
const Symbol &,
bool);
969 static constexpr int startRecursionDepth{100};
971 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
972 inline int RankImpl(
int depth = startRecursionDepth)
const {
976 return common::visit(
978 [&](
const SubprogramDetails &sd) {
979 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
981 [](
const GenericDetails &) {
984 [&](
const ProcBindingDetails &x) {
985 return x.symbol().RankImpl(depth);
987 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
988 [&](
const HostAssocDetails &x) {
989 return x.symbol().RankImpl(depth);
991 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
992 [&](
const ProcEntityDetails &ped) {
993 const Symbol *iface{ped.procInterface()};
994 return iface ? iface->RankImpl(depth) : 0;
996 [](
const AssocEntityDetails &aed) {
997 if (
auto assocRank{aed.rank()}) {
1000 }
else if (aed.IsAssumedRank()) {
1003 }
else if (
const auto &expr{aed.expr()}) {
1004 return expr->Rank();
1009 [](
const auto &) {
return 0; },
1013 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1017 return common::visit(
1019 [&](
const SubprogramDetails &sd) {
1020 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1022 [](
const GenericDetails &) {
return 0; },
1023 [&](
const ProcEntityDetails &ped) {
1024 const Symbol *iface{ped.procInterface()};
1025 return iface ? iface->CorankImpl(depth) : 0;
1027 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1028 [&](
const HostAssocDetails &x) {
1029 return x.symbol().CorankImpl(depth);
1031 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1032 [](
const AssocEntityDetails &aed) {
1033 return aed.expr() ? aed.expr()->Corank() : 0;
1035 [](
const auto &) {
return 0; },
1039 template <std::
size_t>
friend class Symbols;
1040 template <
class, std::
size_t>
friend class std::array;