[flang] review comments

Original-commit: flang-compiler/f18@daaf080dbc
Reviewed-on: https://github.com/flang-compiler/f18/pull/212
This commit is contained in:
peter klausler 2018-10-15 13:39:51 -07:00
parent 51b09b62c6
commit 94041d7667
3 changed files with 42 additions and 7 deletions

View File

@ -199,6 +199,15 @@ struct IntrinsicInterface {
std::ostream &Dump(std::ostream &) const; std::ostream &Dump(std::ostream &) const;
}; };
// GENERIC INTRINSIC FUNCTION INTERFACES
// Each entry in this table defines a pattern. Some intrinsic
// functions have more than one such pattern. Besides the name
// of the intrinsic function, each pattern has specifications for
// the dummy arguments and for the result of the function.
// The dummy argument patterns each have a name (this are from the
// standard, but rarely appear in actual code), a type and kind
// pattern, allowable ranks, and optionality indicators.
// Be advised, the default rank pattern is "elemental".
static const IntrinsicInterface genericIntrinsicFunction[]{ static const IntrinsicInterface genericIntrinsicFunction[]{
{"abs", {{"a", SameIntOrReal}}, SameIntOrReal}, {"abs", {{"a", SameIntOrReal}}, SameIntOrReal},
{"abs", {{"a", SameComplex}}, SameReal}, {"abs", {{"a", SameComplex}}, SameReal},
@ -739,7 +748,7 @@ std::optional<SpecificIntrinsic> IntrinsicInterface::Match(
++dummies) { ++dummies) {
actualForDummy[dummies] = nullptr; actualForDummy[dummies] = nullptr;
} }
for (const ActualArgument &arg : call.argument) { for (const ActualArgument &arg : call.arguments) {
if (arg.isAlternateReturn) { if (arg.isAlternateReturn) {
messages.Say( messages.Say(
"alternate return specifier not acceptable on call to intrinsic '%s'"_err_en_US, "alternate return specifier not acceptable on call to intrinsic '%s'"_err_en_US,
@ -1133,16 +1142,16 @@ std::optional<SpecificIntrinsic> IntrinsicProcTable::Implementation::Probe(
} }
// Special cases of intrinsic functions // Special cases of intrinsic functions
if (call.name.ToString() == "null") { if (call.name.ToString() == "null") {
if (call.argument.size() == 0) { if (call.arguments.size() == 0) {
// TODO: NULL() result type is determined by context // TODO: NULL() result type is determined by context
// Can pass that context in, or return a token distinguishing // Can pass that context in, or return a token distinguishing
// NULL, or represent NULL as a new kind of top-level expression // NULL, or represent NULL as a new kind of top-level expression
} else if (call.argument.size() > 1) { } else if (call.arguments.size() > 1) {
genericErrors.Say("too many arguments to NULL()"_err_en_US); genericErrors.Say("too many arguments to NULL()"_err_en_US);
} else if (call.argument[0].keyword.has_value() && } else if (call.arguments[0].keyword.has_value() &&
call.argument[0].keyword->ToString() != "mold") { call.arguments[0].keyword->ToString() != "mold") {
genericErrors.Say("unknown argument '%s' to NULL()"_err_en_US, genericErrors.Say("unknown argument '%s' to NULL()"_err_en_US,
call.argument[0].keyword->ToString().data()); call.arguments[0].keyword->ToString().data());
} else { } else {
// TODO: Argument must be pointer, procedure pointer, or allocatable. // TODO: Argument must be pointer, procedure pointer, or allocatable.
// Characteristics, including dynamic length type parameter values, // Characteristics, including dynamic length type parameter values,

View File

@ -34,7 +34,7 @@ class Argument;
struct CallCharacteristics { struct CallCharacteristics {
parser::CharBlock name; parser::CharBlock name;
const Arguments &argument; const Arguments &arguments;
bool isSubroutineCall{false}; bool isSubroutineCall{false};
}; };

View File

@ -81,6 +81,13 @@ public:
bool operator>=(const char *that) const { return Compare(that) >= 0; } bool operator>=(const char *that) const { return Compare(that) >= 0; }
bool operator>(const char *that) const { return Compare(that) > 0; } bool operator>(const char *that) const { return Compare(that) > 0; }
friend bool operator<(const char *, const CharBlock &);
friend bool operator<=(const char *, const CharBlock &);
friend bool operator==(const char *, const CharBlock &);
friend bool operator!=(const char *, const CharBlock &);
friend bool operator>=(const char *, const CharBlock &);
friend bool operator>(const char *, const CharBlock &);
private: private:
int Compare(const CharBlock &that) const { int Compare(const CharBlock &that) const {
std::size_t bytes{std::min(size(), that.size())}; std::size_t bytes{std::min(size(), that.size())};
@ -103,6 +110,25 @@ private:
common::Interval<const char *> interval_{nullptr, 0}; common::Interval<const char *> interval_{nullptr, 0};
}; };
inline bool operator<(const char *left, const CharBlock &right) {
return right > left;
}
inline bool operator<=(const char *left, const CharBlock &right) {
return right >= left;
}
inline bool operator==(const char *left, const CharBlock &right) {
return right == left;
}
inline bool operator!=(const char *left, const CharBlock &right) {
return right != left;
}
inline bool operator>=(const char *left, const CharBlock &right) {
return right <= left;
}
inline bool operator>(const char *left, const CharBlock &right) {
return right < left;
}
} // namespace Fortran::parser } // namespace Fortran::parser
// Specializations to enable std::unordered_map<CharBlock, ...> &c. // Specializations to enable std::unordered_map<CharBlock, ...> &c.