blob: f888b83915e585d57e2d7bec8daf68bc4992eaa1 [file]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# antlr4-4.9.3-msvc-compat.patch
#
# Purpose : Make the bundled ANTLR4 C++ runtime (v4.9.3) compile under MSVC
# (Visual Studio 2017 / v141) while keeping the project on C++11.
# Scope : third_party/antlr4-cpp-runtime-4 only. No version change, no
# generated-parser change, no impact on the Java module (also 4.9.3)
# or on embedded/C++11 builds.
# Apply : from the cpp/ directory: git apply patches/antlr4-4.9.3-msvc-compat.patch
# or: patch -p1 < patches/antlr4-4.9.3-msvc-compat.patch
#
# --- Why this is needed -------------------------------------------------------
#
# 1) Token.h / LL1Analyzer.h (overload-resolution ambiguity, error C2668)
# These headers define EPSILON/EOF/HIT_PRED/etc. as either
# `static constexpr size_t` (when __cplusplus >= 201703L) or as members of an
# unnamed `enum : size_t` (otherwise). IntervalSet has both contains(size_t)
# and contains(ssize_t) overloads. Per [conv.prom], converting an unnamed
# enum with a fixed underlying type to that underlying type is an integral
# PROMOTION (a strictly better match than a conversion to ssize_t). GCC
# implements this correctly, so the enum branch compiles there. MSVC 2017
# does NOT -- it ranks both overloads equally and reports an ambiguous call.
# MSVC also reports __cplusplus as 199711L by default, so it always took the
# enum branch. `static constexpr size_t` is fully usable in MSVC 2017's
# C++11 mode, so we let MSVC take the constexpr branch: the constants become
# plain size_t values and the ambiguity disappears with no call-site changes.
# This is ODR-safe: the constants are currently enumerators (which cannot be
# ODR-used), proving the runtime never takes their address.
# NOTE: only the headers whose constants reach IntervalSet::contains/remove
# are patched. The std::string_view guards in ANTLRInputStream.{h,cpp} use
# the same `#if` and are deliberately left untouched (string_view is C++17).
#
# 2) Vocabulary.cpp (error C2039/C2660: isupper)
# Vocabulary.cpp calls the two-argument std::isupper(charT, const locale&)
# from <locale> but never includes <locale>; it relied on a transitive
# include that libstdc++ happens to provide and MSVC's STL does not.
# Fix: add the missing #include <locale>.
#
# ------------------------------------------------------------------------------
--- a/third_party/antlr4-cpp-runtime-4/runtime/src/Token.h
+++ b/third_party/antlr4-cpp-runtime-4/runtime/src/Token.h
@@ -14,7 +14,7 @@
/// we obtained this token.
class ANTLR4CPP_PUBLIC Token {
public:
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L || defined(_MSC_VER)
static constexpr size_t INVALID_TYPE = 0;
#else
enum : size_t {
@@ -24,7 +24,7 @@
/// During lookahead operations, this "token" signifies we hit rule end ATN state
/// and did not follow it despite needing to.
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L || defined(_MSC_VER)
static constexpr size_t EPSILON = std::numeric_limits<size_t>::max() - 1;
static constexpr size_t MIN_USER_TOKEN_TYPE = 1;
static constexpr size_t EOF = IntStream::EOF;
@@ -41,7 +41,7 @@
/// All tokens go to the parser (unless skip() is called in that rule)
/// on a particular "channel". The parser tunes to a particular channel
/// so that whitespace etc... can go to the parser on a "hidden" channel.
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L || defined(_MSC_VER)
static constexpr size_t DEFAULT_CHANNEL = 0;
#else
enum : size_t {
@@ -51,7 +51,7 @@
/// Anything on different channel than DEFAULT_CHANNEL is not parsed
/// by parser.
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L || defined(_MSC_VER)
static constexpr size_t HIDDEN_CHANNEL = 1;
#else
enum : size_t {
@@ -70,7 +70,7 @@
*
* @see Token#getChannel()
*/
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L || defined(_MSC_VER)
static constexpr size_t MIN_USER_CHANNEL_VALUE = 2;
#else
enum : size_t {
--- a/third_party/antlr4-cpp-runtime-4/runtime/src/atn/LL1Analyzer.h
+++ b/third_party/antlr4-cpp-runtime-4/runtime/src/atn/LL1Analyzer.h
@@ -17,7 +17,7 @@
public:
/// Special value added to the lookahead sets to indicate that we hit
/// a predicate during analysis if {@code seeThruPreds==false}.
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L || defined(_MSC_VER)
static constexpr size_t HIT_PRED = Token::INVALID_TYPE;
#else
enum : size_t {
--- a/third_party/antlr4-cpp-runtime-4/runtime/src/Vocabulary.cpp
+++ b/third_party/antlr4-cpp-runtime-4/runtime/src/Vocabulary.cpp
@@ -3,6 +3,8 @@
* can be found in the LICENSE.txt file in the project root.
*/
+#include <locale>
+
#include "Token.h"
#include "Vocabulary.h"