forked from OSchip/llvm-project
[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:
parent
840acd5314
commit
d8f4072aba
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue