[flang] work around template specialization problem

Original-commit: flang-compiler/f18@1d67d72bea
Reviewed-on: https://github.com/flang-compiler/f18/pull/236
This commit is contained in:
peter klausler 2018-12-04 15:52:50 -08:00
parent 840acd5314
commit d8f4072aba
2 changed files with 28 additions and 26 deletions

View File

@ -280,34 +280,18 @@ MaybeExpr AnalyzeExpr(
// Catch-all unwrapper for AnalyzeExpr's most general case.
template<typename A>
MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &context, const A &x) {
// Some compiler/version/option set combinations used to mysteriously
// overlook the template specialization in expression.h that
// redirected parser::Expr arguments, and they would arrive here
// in the catch-all template. We've worked around that problem.
static_assert(
!std::is_same_v<A, parser::Expr>, "template specialization failed");
return AnalyzeExpr(context, x.u);
}
// Definitions of AnalyzeExpr() specializations follow.
// Helper subroutines are intermixed.
// This specialization of AnalyzeExpr() constitutes the main entry point
// to this module from the templates in expression.h.
MaybeExpr AnalyzeExpr(
ExpressionAnalysisContext &context, const parser::Expr &expr) {
if (!expr.source.empty()) {
// Analyze the expression in a specified source position context for better
// error reporting.
auto save{
context.context().foldingContext().messages.SetLocation(expr.source)};
MaybeExpr result{AnalyzeExpr(context, expr.u)};
context.CheckConstraints(result);
return result;
} else {
MaybeExpr result{AnalyzeExpr(context, expr.u)};
context.CheckConstraints(result);
return result;
}
}
template MaybeExpr AnalyzeExpr(
ExpressionAnalysisContext &, const parser::Expr &);
// Variants are silently traversed by AnalyzeExpr().
template<typename... As>
MaybeExpr AnalyzeExpr(
@ -1478,6 +1462,21 @@ MaybeExpr AnalyzeExpr(
context.Say("TODO: DefinedBinary unimplemented"_err_en_US);
return std::nullopt;
}
MaybeExpr ExpressionAnalysisContext::Analyze(const parser::Expr &expr) {
if (!expr.source.empty()) {
// Analyze the expression in a specified source position context for better
// error reporting.
auto save{context_.foldingContext().messages.SetLocation(expr.source)};
MaybeExpr result{AnalyzeExpr(*this, expr.u)};
CheckConstraints(result);
return result;
} else {
MaybeExpr result{AnalyzeExpr(*this, expr.u)};
CheckConstraints(result);
return result;
}
}
}
namespace Fortran::semantics {

View File

@ -74,6 +74,8 @@ public:
bool LogicalConstraint(Expr<SomeType> &);
bool DefaultCharConstraint(Expr<SomeType> &);
std::optional<Expr<SomeType>> Analyze(const parser::Expr &);
protected:
semantics::SemanticsContext &context_;
@ -86,10 +88,11 @@ template<typename PARSED>
std::optional<Expr<SomeType>> AnalyzeExpr(
ExpressionAnalysisContext &, const PARSED &);
// This extern template is the gateway into the rest of the expression
// analysis implementation in expression.cc.
extern template std::optional<Expr<SomeType>> AnalyzeExpr(
ExpressionAnalysisContext &, const parser::Expr &);
template<>
inline std::optional<Expr<SomeType>> AnalyzeExpr(
ExpressionAnalysisContext &context, const parser::Expr &expr) {
return context.Analyze(expr);
}
// Forward declarations of exposed specializations
template<typename A>