55 ENUM_CLASS(Attr, PassedObject, PercentVal, PercentRef);
63 explicit AssumedType(
const Symbol &);
64 DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(AssumedType)
65 const Symbol &symbol()
const {
return symbol_; }
67 bool operator==(
const AssumedType &that)
const {
68 return &*symbol_ == &*that.symbol_;
70 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
76 DECLARE_CONSTRUCTORS_AND_ASSIGNMENTS(ActualArgument)
78 explicit ActualArgument(common::CopyableIndirection<
Expr<SomeType>> &&);
80 explicit ActualArgument(common::Label);
86 std::get_if<common::CopyableIndirection<Expr<SomeType>>>(&u_)}) {
92 const Expr<SomeType> *UnwrapExpr()
const {
94 std::get_if<common::CopyableIndirection<Expr<SomeType>>>(&u_)}) {
101 const Symbol *GetAssumedTypeDummy()
const {
102 if (
const AssumedType * aType{std::get_if<AssumedType>(&u_)}) {
103 return &aType->symbol();
109 common::Label GetLabel()
const {
return std::get<common::Label>(u_); }
111 std::optional<DynamicType> GetType()
const;
113 bool operator==(
const ActualArgument &)
const;
114 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
115 std::string AsFortran()
const;
117 std::optional<parser::CharBlock> keyword()
const {
return keyword_; }
118 ActualArgument &set_keyword(parser::CharBlock x) {
122 bool isAlternateReturn()
const {
123 return std::holds_alternative<common::Label>(u_);
125 bool isPassedObject()
const {
return attrs_.test(Attr::PassedObject); }
126 ActualArgument &set_isPassedObject(
bool yes =
true) {
128 attrs_ = attrs_ + Attr::PassedObject;
130 attrs_ = attrs_ - Attr::PassedObject;
135 bool Matches(
const characteristics::DummyArgument &)
const;
136 common::Intent dummyIntent()
const {
return dummyIntent_; }
137 ActualArgument &set_dummyIntent(common::Intent intent) {
138 dummyIntent_ = intent;
141 std::optional<parser::CharBlock> sourceLocation()
const {
142 return sourceLocation_;
144 ActualArgument &set_sourceLocation(std::optional<parser::CharBlock> at) {
145 sourceLocation_ = at;
153 bool isPercentVal()
const {
return attrs_.test(Attr::PercentVal); };
154 ActualArgument &set_isPercentVal() {
155 attrs_ = attrs_ + Attr::PercentVal;
159 bool isPercentRef()
const {
return attrs_.test(Attr::PercentRef); };
160 ActualArgument &set_isPercentRef() {
161 attrs_ = attrs_ + Attr::PercentRef;
171 std::variant<common::CopyableIndirection<Expr<SomeType>>,
AssumedType,
174 std::optional<parser::CharBlock> keyword_;
176 common::Intent dummyIntent_{common::Intent::Default};
177 std::optional<parser::CharBlock> sourceLocation_;
198struct ProcedureDesignator {
199 EVALUATE_UNION_CLASS_BOILERPLATE(ProcedureDesignator)
201 explicit ProcedureDesignator(
const Symbol &n) : u{n} {}
202 explicit ProcedureDesignator(
Component &&);
206 const Symbol *GetSymbol()
const;
207 const SymbolRef *UnwrapSymbolRef()
const;
216 const Symbol *GetInterfaceSymbol()
const;
218 std::string GetName()
const;
219 std::optional<DynamicType> GetType()
const;
221 bool IsElemental()
const;
223 std::optional<Expr<SubscriptInteger>> LEN()
const;
224 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
227 common::CopyableIndirection<Component>>
235 CLASS_BOILERPLATE(ProcedureRef)
237 bool hasAlternateReturns =
false)
238 : proc_{std::move(p)}, arguments_{std::move(a)},
239 hasAlternateReturns_{hasAlternateReturns} {}
241 static void Deleter(ProcedureRef *);
245 ActualArguments &arguments() {
return arguments_; }
246 const ActualArguments &arguments()
const {
return arguments_; }
248 Chevrons &chevrons() {
return chevrons_; }
249 const Chevrons &chevrons()
const {
return chevrons_; }
250 void set_chevrons(Chevrons &&chevrons) { chevrons_ = std::move(chevrons); }
252 std::optional<Expr<SubscriptInteger>> LEN()
const;
254 static constexpr int Corank() {
return 0; }
255 bool IsElemental()
const {
return proc_.IsElemental(); }
256 bool hasAlternateReturns()
const {
return hasAlternateReturns_; }
258 bool hasNoInline()
const {
return noInline_; }
259 void setNoInline(
bool ni) { noInline_ = ni; }
260 bool hasAlwaysInline()
const {
return alwaysInline_; }
261 void setAlwaysInline(
bool ai) { alwaysInline_ = ai; }
262 bool hasInlineHint()
const {
return inlineHint_; }
263 void setInlineHint(
bool ih) { inlineHint_ = ih; }
266 if (
static_cast<std::size_t
>(n) < arguments_.size() && arguments_[n]) {
267 return arguments_[n]->UnwrapExpr();
273 if (
static_cast<std::size_t
>(n) < arguments_.size() && arguments_[n]) {
274 return arguments_[n]->UnwrapExpr();
280 bool operator==(
const ProcedureRef &)
const;
281 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
285 ActualArguments arguments_;
287 bool hasAlternateReturns_;
288 bool noInline_{
false};
289 bool alwaysInline_{
false};
290 bool inlineHint_{
false};
293template <
typename A>
class FunctionRef :
public ProcedureRef {
296 CLASS_BOILERPLATE(FunctionRef)
297 explicit FunctionRef(ProcedureRef &&pr) : ProcedureRef{std::move(pr)} {}
299 : ProcedureRef{std::move(p), std::move(a)} {}
301 std::optional<DynamicType> GetType()
const {
302 if constexpr (IsLengthlessIntrinsicType<A>) {
304 }
else if (
auto type{proc_.GetType()}) {
310 return type->DropNonConstantCharacterLength();