[flang] Add passArg to ProcEntityDetails and ProcBindingDetails

Add `passArg` to `ProcEntityDetails` and `ProcBindingDetails`.
The is the symbols that represents the passed-object dummy argument,
or nullptr if none.

As both of these classes need `passName` and `passArg`, create a mixin
class, `WithPassArg` for the shared content.

Change passName_ from optional to pointer because that makes it a little
easier to work with and there is no need to have a copy of the name.

Original-commit: flang-compiler/f18@1cdd1a5b87
Reviewed-on: https://github.com/flang-compiler/f18/pull/521
Tree-same-pre-rewrite: false
This commit is contained in:
Tim Keith 2019-06-22 10:00:18 -07:00
parent 9a98616dbb
commit 432e62b417
4 changed files with 23 additions and 20 deletions

View file

@ -43,7 +43,7 @@ static std::vector<const Symbol *> CollectSymbols(const Scope &);
static void PutEntity(std::ostream &, const Symbol &);
static void PutObjectEntity(std::ostream &, const Symbol &);
static void PutProcEntity(std::ostream &, const Symbol &);
static void PutPassName(std::ostream &, const std::optional<SourceName> &);
static void PutPassName(std::ostream &, const SourceName *);
static void PutTypeParam(std::ostream &, const Symbol &);
static void PutEntity(std::ostream &, const Symbol &, std::function<void()>);
static void PutInit(std::ostream &, const MaybeExpr &);
@ -488,7 +488,7 @@ void PutProcEntity(std::ostream &os, const Symbol &symbol) {
});
}
void PutPassName(std::ostream &os, const std::optional<SourceName> &passName) {
void PutPassName(std::ostream &os, const SourceName *passName) {
if (passName) {
PutLower(os << ",pass(", passName->ToString()) << ')';
}

View file

@ -270,7 +270,7 @@ protected:
private:
MaybeExpr bindName_; // from BIND(C, NAME="...")
std::optional<SourceName> passName_; // from PASS(...)
const SourceName *passName_{nullptr}; // from PASS(...)
};
// Find and create types from declaration-type-spec nodes.
@ -1159,10 +1159,9 @@ Attrs AttrsVisitor::GetAttrs() {
return *attrs_;
}
Attrs AttrsVisitor::EndAttrs() {
CHECK(attrs_);
Attrs result{*attrs_};
Attrs result{GetAttrs()};
attrs_.reset();
passName_.reset();
passName_ = nullptr;
bindName_.reset();
return result;
}
@ -1216,7 +1215,7 @@ bool AttrsVisitor::Pre(const parser::IntentSpec &x) {
}
bool AttrsVisitor::Pre(const parser::Pass &x) {
if (x.v) {
passName_ = x.v->source;
passName_ = &x.v->source;
MakePlaceholder(*x.v, MiscDetails::Kind::PassName);
} else {
attrs_->set(Attr::PASS);

View file

@ -27,8 +27,7 @@ std::ostream &operator<<(std::ostream &os, const parser::CharBlock &name) {
}
template<typename T>
static void DumpOptional(
std::ostream &os, const char *label, const std::optional<T> &x) {
static void DumpOptional(std::ostream &os, const char *label, const T &x) {
if (x) {
os << ' ' << label << ':' << *x;
}
@ -435,9 +434,7 @@ std::ostream &operator<<(std::ostream &os, const Details &details) {
},
[&](const FinalProcDetails &) {},
[&](const TypeParamDetails &x) {
if (x.type()) {
os << ' ' << *x.type();
}
DumpOptional(os, "type", x.type());
os << ' ' << common::EnumToString(x.attr());
DumpOptional(os, "init", x.init());
},

View file

@ -189,8 +189,21 @@ private:
friend std::ostream &operator<<(std::ostream &, const ObjectEntityDetails &);
};
// Mixin for details with passed-object dummy argument.
class WithPassArg {
public:
const SourceName *passName() const { return passName_; }
void set_passName(const SourceName &passName) { passName_ = &passName; }
const Symbol *passArg() const { return passArg_; }
void set_passArg(const Symbol *passArg) { passArg_ = passArg; }
private:
const SourceName *passName_{nullptr};
const Symbol *passArg_{nullptr};
};
// A procedure pointer, dummy procedure, or external procedure
class ProcEntityDetails : public EntityDetails {
class ProcEntityDetails : public EntityDetails, public WithPassArg {
public:
ProcEntityDetails() = default;
explicit ProcEntityDetails(EntityDetails &&d);
@ -198,13 +211,10 @@ public:
const ProcInterface &interface() const { return interface_; }
ProcInterface &interface() { return interface_; }
void set_interface(const ProcInterface &interface) { interface_ = interface; }
const std::optional<SourceName> &passName() const { return passName_; }
void set_passName(const SourceName &passName) { passName_ = passName; }
inline bool HasExplicitInterface() const;
private:
ProcInterface interface_;
std::optional<SourceName> passName_;
friend std::ostream &operator<<(std::ostream &, const ProcEntityDetails &);
};
@ -263,16 +273,13 @@ private:
friend std::ostream &operator<<(std::ostream &, const DerivedTypeDetails &);
};
class ProcBindingDetails {
class ProcBindingDetails : public WithPassArg {
public:
explicit ProcBindingDetails(const Symbol &symbol) : symbol_{&symbol} {}
const Symbol &symbol() const { return *symbol_; }
std::optional<SourceName> passName() const { return passName_; }
void set_passName(const SourceName &passName) { passName_ = passName; }
private:
const Symbol *symbol_; // procedure bound to
std::optional<SourceName> passName_; // name in PASS attribute
};
ENUM_CLASS(GenericKind, // Kinds of generic-spec