133class OpenACCRoutineDeviceTypeInfo {
135 explicit OpenACCRoutineDeviceTypeInfo(
136 Fortran::common::OpenACCDeviceType dType)
137 : deviceType_{dType} {}
138 bool isSeq()
const {
return isSeq_; }
139 void set_isSeq(
bool value =
true) { isSeq_ = value; }
140 bool isVector()
const {
return isVector_; }
141 void set_isVector(
bool value =
true) { isVector_ = value; }
142 bool isWorker()
const {
return isWorker_; }
143 void set_isWorker(
bool value =
true) { isWorker_ = value; }
144 bool isGang()
const {
return isGang_; }
145 void set_isGang(
bool value =
true) { isGang_ = value; }
146 unsigned gangDim()
const {
return gangDim_; }
147 void set_gangDim(
unsigned value) { gangDim_ = value; }
148 const std::variant<std::string, SymbolRef> *bindName()
const {
149 return bindName_.has_value() ? &*bindName_ :
nullptr;
151 const std::optional<std::variant<std::string, SymbolRef>> &
152 bindNameOpt()
const {
155 void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
156 void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
158 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
160 friend llvm::raw_ostream &operator<<(
161 llvm::raw_ostream &,
const OpenACCRoutineDeviceTypeInfo &);
165 bool isVector_{
false};
166 bool isWorker_{
false};
168 unsigned gangDim_{0};
171 std::optional<std::variant<std::string, SymbolRef>> bindName_;
172 Fortran::common::OpenACCDeviceType deviceType_{
173 Fortran::common::OpenACCDeviceType::None};
214 bool isFunction()
const {
return result_ !=
nullptr; }
215 bool isInterface()
const {
return isInterface_; }
216 void set_isInterface(
bool value =
true) { isInterface_ = value; }
217 bool isDummy()
const {
return isDummy_; }
218 void set_isDummy(
bool value =
true) { isDummy_ = value; }
219 Scope *entryScope() {
return entryScope_; }
220 const Scope *entryScope()
const {
return entryScope_; }
221 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
222 const Symbol &result()
const {
226 void set_result(
Symbol &result) {
230 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
231 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
232 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
233 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
234 void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
235 Symbol *moduleInterface() {
return moduleInterface_; }
236 const Symbol *moduleInterface()
const {
return moduleInterface_; }
237 void set_moduleInterface(
Symbol &);
238 void ReplaceResult(
Symbol &result) {
239 CHECK(result_ !=
nullptr);
242 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
243 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
244 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
245 return cudaSubprogramAttrs_;
247 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
248 cudaSubprogramAttrs_ = csas;
250 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
251 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
252 return cudaLaunchBounds_;
254 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
255 cudaLaunchBounds_ = std::move(x);
257 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
258 const std::vector<std::int64_t> &cudaClusterDims()
const {
259 return cudaClusterDims_;
261 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
262 cudaClusterDims_ = std::move(x);
264 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
265 return openACCRoutineInfos_;
268 openACCRoutineInfos_.push_back(info);
272 bool isInterface_{
false};
273 bool isDummy_{
false};
274 std::vector<Symbol *> dummyArgs_;
276 Scope *entryScope_{
nullptr};
277 MaybeExpr stmtFunction_;
281 Symbol *moduleInterface_{
nullptr};
282 bool defaultIgnoreTKR_{
false};
284 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
286 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
288 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
290 friend llvm::raw_ostream &operator<<(
380class ObjectEntityDetails :
public EntityDetails {
382 explicit ObjectEntityDetails(EntityDetails &&);
383 ObjectEntityDetails(
const ObjectEntityDetails &) =
default;
384 ObjectEntityDetails(ObjectEntityDetails &&) =
default;
385 ObjectEntityDetails &operator=(
const ObjectEntityDetails &) =
default;
386 ObjectEntityDetails(
bool isDummy =
false) : EntityDetails(isDummy) {}
387 MaybeExpr &init() {
return init_; }
388 const MaybeExpr &init()
const {
return init_; }
389 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
390 const parser::Expr *unanalyzedPDTComponentInit()
const {
391 return unanalyzedPDTComponentInit_;
393 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
394 unanalyzedPDTComponentInit_ = expr;
397 const ArraySpec &shape()
const {
return shape_; }
398 ArraySpec &coshape() {
return coshape_; }
399 const ArraySpec &coshape()
const {
return coshape_; }
402 const Symbol *commonBlock()
const {
return commonBlock_; }
403 void set_commonBlock(
const Symbol &commonBlock) {
404 commonBlock_ = &commonBlock;
406 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
407 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
408 bool IsArray()
const {
return !shape_.empty(); }
409 bool IsCoarray()
const {
return !coshape_.empty(); }
410 bool IsAssumedShape()
const {
411 return isDummy() && shape_.CanBeAssumedShape();
413 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
414 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
415 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
416 return cudaDataAttr_;
418 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
419 cudaDataAttr_ = attr;
424 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
427 common::IgnoreTKRSet ignoreTKR_;
428 const Symbol *commonBlock_{
nullptr};
429 std::optional<common::CUDADataAttr> cudaDataAttr_;
430 friend llvm::raw_ostream &operator<<(
431 llvm::raw_ostream &,
const ObjectEntityDetails &);
451class ProcEntityDetails :
public EntityDetails,
public WithPassArg {
453 ProcEntityDetails() =
default;
454 explicit ProcEntityDetails(EntityDetails &&);
455 ProcEntityDetails(
const ProcEntityDetails &) =
default;
456 ProcEntityDetails(ProcEntityDetails &&) =
default;
457 ProcEntityDetails &operator=(
const ProcEntityDetails &) =
default;
459 const Symbol *rawProcInterface()
const {
return rawProcInterface_; }
460 const Symbol *procInterface()
const {
return procInterface_; }
461 void set_procInterfaces(
const Symbol &raw,
const Symbol &resolved) {
462 rawProcInterface_ = &raw;
463 procInterface_ = &resolved;
465 inline bool HasExplicitInterface()
const;
469 std::optional<const Symbol *> init()
const {
return init_; }
470 void set_init(
const Symbol &symbol) { init_ = &symbol; }
471 void set_init(std::nullptr_t) { init_ =
nullptr; }
472 bool isCUDAKernel()
const {
return isCUDAKernel_; }
473 void set_isCUDAKernel(
bool yes =
true) { isCUDAKernel_ = yes; }
474 std::optional<SourceName> usedAsProcedureHere()
const {
475 return usedAsProcedureHere_;
477 void set_usedAsProcedureHere(SourceName here) { usedAsProcedureHere_ = here; }
478 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
479 return openACCRoutineInfos_;
482 openACCRoutineInfos_.push_back(info);
486 const Symbol *rawProcInterface_{
nullptr};
487 const Symbol *procInterface_{
nullptr};
488 std::optional<const Symbol *> init_;
489 bool isCUDAKernel_{
false};
490 std::optional<SourceName> usedAsProcedureHere_;
491 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
492 friend llvm::raw_ostream &operator<<(
493 llvm::raw_ostream &,
const ProcEntityDetails &);
503 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
504 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
505 bool sequence()
const {
return sequence_; }
506 bool isDECStructure()
const {
return isDECStructure_; }
507 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
508 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
509 bool isForwardReferenced()
const {
return isForwardReferenced_; }
510 void add_paramNameOrder(
const Symbol &symbol) {
511 paramNameOrder_.push_back(symbol);
513 void add_paramDeclOrder(
const Symbol &symbol) {
514 paramDeclOrder_.push_back(symbol);
516 void add_component(
const Symbol &);
517 void set_sequence(
bool x =
true) { sequence_ = x; }
518 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
519 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
520 const std::list<SourceName> &componentNames()
const {
521 return componentNames_;
523 const std::map<SourceName, const parser::Expr *> &
524 originalKindParameterMap()
const {
525 return originalKindParameterMap_;
527 void add_originalKindParameter(SourceName,
const parser::Expr *);
530 const Symbol *GetParentComponent(
const Scope &)
const;
532 std::optional<SourceName> GetParentComponentName()
const {
533 if (componentNames_.empty()) {
536 return componentNames_.front();
540 const Symbol *GetFinalForRank(
int)
const;
547 SymbolVector paramNameOrder_;
548 SymbolVector paramDeclOrder_;
551 std::list<SourceName> componentNames_;
552 std::map<SourceName, SymbolRef> finals_;
553 bool sequence_{
false};
554 bool isDECStructure_{
false};
555 bool isForwardReferenced_{
false};
556 std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
558 friend llvm::raw_ostream &operator<<(
842 CrayPointer, CrayPointee,
856 AccPrivate, AccFirstPrivate, AccShared,
858 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
859 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
863 AccDevice, AccHost, AccSelf,
865 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
867 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
870 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
871 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
873 OmpCopyIn, OmpCopyPrivate,
875 OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
877 OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
878 OmpAllocate, OmpDeclarativeAllocateDirective,
879 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
880 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
881 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
882 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
886 const Scope &owner()
const {
return *owner_; }
887 const SourceName &name()
const {
return name_; }
888 Attrs &attrs() {
return attrs_; }
889 const Attrs &attrs()
const {
return attrs_; }
890 Attrs &implicitAttrs() {
return implicitAttrs_; }
891 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
892 Flags &flags() {
return flags_; }
893 const Flags &flags()
const {
return flags_; }
894 bool test(Flag flag)
const {
return flags_.test(flag); }
895 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
897 Scope *scope() {
return scope_; }
898 const Scope *scope()
const {
return scope_; }
899 void set_scope(Scope *scope) { scope_ = scope; }
900 std::size_t size()
const {
return size_; }
901 void set_size(std::size_t size) { size_ = size; }
902 std::size_t offset()
const {
return offset_; }
903 void set_offset(std::size_t offset) { offset_ = offset; }
905 void ReplaceName(
const SourceName &);
906 static std::string OmpFlagToClauseName(Flag ompFlag);
909 template <
typename D>
bool has()
const {
910 return std::holds_alternative<D>(details_);
914 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
915 template <
typename D>
const D *detailsIf()
const {
916 return std::get_if<D>(&details_);
920 template <
typename D> D &get() {
921 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
923 template <
typename D>
const D &get()
const {
924 const auto *p{detailsIf<D>()};
929 Details &details() {
return details_; }
930 const Details &details()
const {
return details_; }
933 void set_details(Details &&);
936 bool CanReplaceDetails(
const Details &details)
const;
939 inline Symbol &GetUltimate();
940 inline const Symbol &GetUltimate()
const;
942 inline DeclTypeSpec *GetType();
943 inline const DeclTypeSpec *GetType()
const;
944 void SetType(
const DeclTypeSpec &);
946 const std::string *GetBindName()
const;
947 void SetBindName(std::string &&);
948 bool GetIsExplicitBindName()
const;
949 void SetIsExplicitBindName(
bool);
950 void SetIsCDefined(
bool);
951 bool IsFuncResult()
const;
952 bool IsObjectArray()
const;
953 const ArraySpec *GetShape()
const;
954 bool IsSubprogram()
const;
955 bool IsFromModFile()
const;
956 bool HasExplicitInterface()
const {
957 return common::visit(
959 [](
const SubprogramDetails &) {
return true; },
960 [](
const SubprogramNameDetails &) {
return true; },
961 [&](
const ProcEntityDetails &x) {
962 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
964 [](
const ProcBindingDetails &x) {
965 return x.symbol().HasExplicitInterface();
967 [](
const UseDetails &x) {
968 return x.symbol().HasExplicitInterface();
970 [](
const HostAssocDetails &x) {
971 return x.symbol().HasExplicitInterface();
973 [](
const GenericDetails &x) {
974 return x.specific() && x.specific()->HasExplicitInterface();
976 [](
const auto &) {
return false; },
980 bool HasLocalLocality()
const {
981 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
984 bool operator==(
const Symbol &that)
const {
return this == &that; }
985 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
987 int Rank()
const {
return RankImpl(); }
988 int Corank()
const {
return CorankImpl(); }
993 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
998 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
1000 SemanticsContext &GetSemanticsContext()
const;
1001#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1002 LLVM_DUMP_METHOD
void dump()
const;
1006 const Scope *owner_;
1009 Attrs implicitAttrs_;
1011 Scope *scope_{
nullptr};
1012 std::size_t size_{0};
1013 std::size_t offset_{0};
1017 std::string GetDetailsName()
const;
1018 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
1019 friend llvm::raw_ostream &DumpForUnparse(
1020 llvm::raw_ostream &,
const Symbol &,
bool);
1022 static constexpr int startRecursionDepth{100};
1024 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
1025 inline int RankImpl(
int depth = startRecursionDepth)
const {
1029 return common::visit(
1031 [&](
const SubprogramDetails &sd) {
1032 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
1034 [](
const GenericDetails &) {
1037 [&](
const ProcBindingDetails &x) {
1038 return x.symbol().RankImpl(depth);
1040 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
1041 [&](
const HostAssocDetails &x) {
1042 return x.symbol().RankImpl(depth);
1044 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1045 [&](
const ProcEntityDetails &ped) {
1046 const Symbol *iface{ped.procInterface()};
1047 return iface ? iface->RankImpl(depth) : 0;
1049 [](
const AssocEntityDetails &aed) {
1050 if (
auto assocRank{aed.rank()}) {
1053 }
else if (aed.IsAssumedRank()) {
1056 }
else if (
const auto &expr{aed.expr()}) {
1057 return expr->Rank();
1062 [](
const auto &) {
return 0; },
1066 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1070 return common::visit(
1072 [&](
const SubprogramDetails &sd) {
1073 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1075 [](
const GenericDetails &) {
return 0; },
1076 [&](
const ProcEntityDetails &ped) {
1077 const Symbol *iface{ped.procInterface()};
1078 return iface ? iface->CorankImpl(depth) : 0;
1080 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1081 [&](
const HostAssocDetails &x) {
1082 return x.symbol().CorankImpl(depth);
1084 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1085 [](
const AssocEntityDetails &aed) {
1086 return aed.expr() ? aed.expr()->Corank() : 0;
1088 [](
const auto &) {
return 0; },
1092 template <std::
size_t>
friend class Symbols;
1093 template <
class, std::
size_t>
friend class std::array;