summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libcxxabi/src/cxa_demangle.cpp7
-rw-r--r--libcxxabi/src/demangle/DemangleConfig.h (renamed from libcxxabi/src/demangle/Compiler.h)12
-rw-r--r--libcxxabi/src/demangle/ItaniumDemangle.h30
-rw-r--r--libcxxabi/src/demangle/README.txt52
-rw-r--r--libcxxabi/src/demangle/StringView.h41
-rw-r--r--libcxxabi/src/demangle/Utility.h14
-rwxr-xr-xlibcxxabi/src/demangle/cp-to-llvm.sh27
-rw-r--r--llvm/include/llvm/Demangle/DemangleConfig.h (renamed from llvm/include/llvm/Demangle/Compiler.h)51
-rw-r--r--llvm/include/llvm/Demangle/ItaniumDemangle.h35
-rw-r--r--llvm/include/llvm/Demangle/MicrosoftDemangle.h2
-rw-r--r--llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h24
-rw-r--r--llvm/include/llvm/Demangle/README.txt52
-rw-r--r--llvm/include/llvm/Demangle/StringView.h16
-rw-r--r--llvm/include/llvm/Demangle/Utility.h13
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp20
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangleNodes.cpp2
-rw-r--r--llvm/lib/Support/ItaniumManglingCanonicalizer.cpp1
17 files changed, 301 insertions, 98 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp
index f227addbdae..7e8f7191585 100644
--- a/libcxxabi/src/cxa_demangle.cpp
+++ b/libcxxabi/src/cxa_demangle.cpp
@@ -11,12 +11,8 @@
// file does not yet support:
// - C++ modules TS
-#define _LIBCPP_NO_EXCEPTIONS
-
-#include "__cxxabi_config.h"
-
#include "demangle/ItaniumDemangle.h"
-
+#include "__cxxabi_config.h"
#include <cassert>
#include <cctype>
#include <cstdio>
@@ -25,7 +21,6 @@
#include <functional>
#include <numeric>
#include <utility>
-#include <vector>
using namespace itanium_demangle;
diff --git a/libcxxabi/src/demangle/Compiler.h b/libcxxabi/src/demangle/DemangleConfig.h
index e5f3c72a451..3be1ccd15ae 100644
--- a/libcxxabi/src/demangle/Compiler.h
+++ b/libcxxabi/src/demangle/DemangleConfig.h
@@ -12,6 +12,8 @@
#ifndef LIBCXX_DEMANGLE_COMPILER_H
#define LIBCXX_DEMANGLE_COMPILER_H
+#include "__config"
+
#ifdef _MSC_VER
// snprintf is implemented in VS 2015
#if _MSC_VER < 1900
@@ -25,10 +27,16 @@
#ifndef NDEBUG
#if __has_attribute(noinline) && __has_attribute(used)
-#define DUMP_METHOD __attribute__((noinline, used))
+#define DEMANGLE_DUMP_METHOD __attribute__((noinline, used))
#else
-#define DUMP_METHOD
+#define DEMANGLE_DUMP_METHOD
#endif
#endif
+#define DEMANGLE_FALLTHROUGH _LIBCPP_FALLTHROUGH()
+#define DEMANGLE_UNREACHABLE _LIBCPP_UNREACHABLE()
+
+#define DEMANGLE_NAMESPACE_BEGIN namespace { namespace itanium_demangle {
+#define DEMANGLE_NAMESPACE_END } }
+
#endif
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 9e9d183da7c..53107c9c8d9 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -7,22 +7,21 @@
//
//===----------------------------------------------------------------------===//
//
-// WARNING: This file defines its contents within an anonymous namespace. It
-// should not be included anywhere other than cxa_demangle.h.
+// Generic itanium demangler library. This file has two byte-per-byte identical
+// copies in the source tree, one in libcxxabi, and the other in llvm.
//
//===----------------------------------------------------------------------===//
-#ifndef LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H
-#define LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H
+#ifndef DEMANGLE_ITANIUMDEMANGLE_H
+#define DEMANGLE_ITANIUMDEMANGLE_H
// FIXME: (possibly) incomplete list of features that clang mangles that this
// file does not yet support:
// - C++ modules TS
-#include "Compiler.h"
+#include "DemangleConfig.h"
#include "StringView.h"
#include "Utility.h"
-
#include <cassert>
#include <cctype>
#include <cstdio>
@@ -100,8 +99,8 @@
X(BracedExpr) \
X(BracedRangeExpr)
-namespace {
-namespace itanium_demangle {
+DEMANGLE_NAMESPACE_BEGIN
+
// Base class of all AST nodes. The AST is built by the parser, then is
// traversed by the printLeft/Right functions to produce a demangled string.
class Node {
@@ -199,7 +198,7 @@ public:
virtual ~Node() = default;
#ifndef NDEBUG
- DUMP_METHOD void dump() const;
+ DEMANGLE_DUMP_METHOD void dump() const;
#endif
};
@@ -1283,7 +1282,7 @@ public:
case SpecialSubKind::iostream:
return StringView("basic_iostream");
}
- _LIBCPP_UNREACHABLE();
+ DEMANGLE_UNREACHABLE;
}
void printLeft(OutputStream &S) const override {
@@ -1335,7 +1334,7 @@ public:
case SpecialSubKind::iostream:
return StringView("iostream");
}
- _LIBCPP_UNREACHABLE();
+ DEMANGLE_UNREACHABLE;
}
void printLeft(OutputStream &S) const override {
@@ -3472,7 +3471,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
Result = getDerived().parseFunctionType();
break;
}
- _LIBCPP_FALLTHROUGH();
+ DEMANGLE_FALLTHROUGH;
}
case 'U': {
Result = getDerived().parseQualifiedType();
@@ -3759,7 +3758,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
// substitution table.
return Sub;
}
- _LIBCPP_FALLTHROUGH();
+ DEMANGLE_FALLTHROUGH;
}
// ::= <class-enum-type>
default: {
@@ -5183,7 +5182,6 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
Alloc>::AbstractManglingParser;
};
-} // namespace itanium_demangle
-} // namespace
+DEMANGLE_NAMESPACE_END
-#endif // LIBCXX_DEMANGLE_ITANIUMDEMANGLE_H
+#endif // DEMANGLE_ITANIUMDEMANGLE_H
diff --git a/libcxxabi/src/demangle/README.txt b/libcxxabi/src/demangle/README.txt
new file mode 100644
index 00000000000..514ff6dd16f
--- /dev/null
+++ b/libcxxabi/src/demangle/README.txt
@@ -0,0 +1,52 @@
+Itanium Name Demangler Library
+==============================
+
+Introduction
+------------
+
+This directory contains the generic itanium name demangler library. The main
+purpose of the library is to demangle C++ symbols, i.e. convert the string
+"_Z1fv" into "f()". You can also use the CRTP base ManglingParser to perform
+some simple analysis on the mangled name, or (in LLVM) use the opaque
+ItaniumPartialDemangler to query the demangled AST.
+
+Why are there multiple copies of the this library in the source tree?
+---------------------------------------------------------------------
+
+This directory is mirrored between libcxxabi/demangle and
+llvm/include/llvm/Demangle. The simple reason for this is that both projects
+need to demangle symbols, but neither can depend on each other. libcxxabi needs
+the demangler to implement __cxa_demangle, which is part of the itanium ABI
+spec. LLVM needs a copy for a bunch of places, but doesn't want to use the
+system's __cxa_demangle because it a) might not be available (i.e., on Windows),
+and b) probably isn't that up-to-date on the latest language features.
+
+The copy of the demangler in LLVM has some extra stuff that aren't needed in
+libcxxabi (ie, the MSVC demangler, ItaniumPartialDemangler), which depend on the
+shared generic components. Despite these differences, we want to keep the "core"
+generic demangling library identical between both copies to simplify development
+and testing.
+
+If you're working on the generic library, then do the work first in libcxxabi,
+then run the cp-to-llvm.sh script in src/demangle. This script takes as an
+argument the path to llvm, and re-copies the changes you made to libcxxabi over.
+Note that this script just blindly overwrites all changes to the generic library
+in llvm, so be careful.
+
+Because the core demangler needs to work in libcxxabi, everything needs to be
+declared in an anonymous namespace (see DEMANGLE_NAMESPACE_BEGIN), and you can't
+introduce any code that depends on the libcxx dylib.
+
+Hopefully, when LLVM becomes a monorepo, we can de-duplicate this code, and have
+both LLVM and libcxxabi depend on a shared demangler library.
+
+Testing
+-------
+
+The tests are split up between libcxxabi/test/{unit,}test_demangle.cpp, and
+llvm/unittest/Demangle. The llvm directory should only get tests for stuff not
+included in the core library. In the future though, we should probably move all
+the tests to LLVM.
+
+It is also a really good idea to run libFuzzer after non-trivial changes, see
+libcxxabi/fuzz/cxa_demangle_fuzzer.cpp and https://llvm.org/docs/LibFuzzer.html.
diff --git a/libcxxabi/src/demangle/StringView.h b/libcxxabi/src/demangle/StringView.h
index 986f2defc08..9af4e0684ea 100644
--- a/libcxxabi/src/demangle/StringView.h
+++ b/libcxxabi/src/demangle/StringView.h
@@ -5,23 +5,29 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
+//===----------------------------------------------------------------------===//
+//
+// FIXME: Use std::string_view instead when we support C++17.
//
-// This file is copied from llvm/lib/Demangle/StringView.h.
//===----------------------------------------------------------------------===//
-#ifndef LIBCXX_DEMANGLE_STRINGVIEW_H
-#define LIBCXX_DEMANGLE_STRINGVIEW_H
+#ifndef DEMANGLE_STRINGVIEW_H
+#define DEMANGLE_STRINGVIEW_H
+#include "DemangleConfig.h"
#include <algorithm>
#include <cassert>
#include <cstring>
-namespace {
+DEMANGLE_NAMESPACE_BEGIN
+
class StringView {
const char *First;
const char *Last;
public:
+ static const size_t npos = ~size_t(0);
+
template <size_t N>
StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
StringView(const char *First_, const char *Last_)
@@ -35,6 +41,17 @@ public:
return StringView(begin() + From, size() - From);
}
+ size_t find(char C, size_t From = 0) const {
+ size_t FindBegin = std::min(From, size());
+ // Avoid calling memchr with nullptr.
+ if (FindBegin < size()) {
+ // Just forward to memchr, which is faster than a hand-rolled loop.
+ if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
+ return size_t(static_cast<const char *>(P) - First);
+ }
+ return npos;
+ }
+
StringView substr(size_t From, size_t To) const {
if (To >= size())
To = size() - 1;
@@ -45,15 +62,26 @@ public:
StringView dropFront(size_t N = 1) const {
if (N >= size())
- N = size() - 1;
+ N = size();
return StringView(First + N, Last);
}
+ StringView dropBack(size_t N = 1) const {
+ if (N >= size())
+ N = size();
+ return StringView(First, Last - N);
+ }
+
char front() const {
assert(!empty());
return *begin();
}
+ char back() const {
+ assert(!empty());
+ return *(end() - 1);
+ }
+
char popFront() {
assert(!empty());
return *First++;
@@ -93,6 +121,7 @@ inline bool operator==(const StringView &LHS, const StringView &RHS) {
return LHS.size() == RHS.size() &&
std::equal(LHS.begin(), LHS.end(), RHS.begin());
}
-} // namespace
+
+DEMANGLE_NAMESPACE_END
#endif
diff --git a/libcxxabi/src/demangle/Utility.h b/libcxxabi/src/demangle/Utility.h
index b5e9b5e42cf..4d44cd8f5a1 100644
--- a/libcxxabi/src/demangle/Utility.h
+++ b/libcxxabi/src/demangle/Utility.h
@@ -5,22 +5,24 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
+//===----------------------------------------------------------------------===//
+//
+// Provide some utility classes for use in the demangler(s).
//
-// This file is copied from llvm/lib/Demangle/Utility.h.
//===----------------------------------------------------------------------===//
-#ifndef LIBCXX_DEMANGLE_UTILITY_H
-#define LIBCXX_DEMANGLE_UTILITY_H
+#ifndef DEMANGLE_UTILITY_H
+#define DEMANGLE_UTILITY_H
#include "StringView.h"
-
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <limits>
-namespace {
+DEMANGLE_NAMESPACE_BEGIN
+
// Stream that AST nodes write their string representation into after the AST
// has been parsed.
class OutputStream {
@@ -185,6 +187,6 @@ inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
return true;
}
-} // namespace
+DEMANGLE_NAMESPACE_END
#endif
diff --git a/libcxxabi/src/demangle/cp-to-llvm.sh b/libcxxabi/src/demangle/cp-to-llvm.sh
new file mode 100755
index 00000000000..808abbcd99b
--- /dev/null
+++ b/libcxxabi/src/demangle/cp-to-llvm.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Copies the 'demangle' library, excluding 'DemangleConfig.h', to llvm. If no
+# llvm directory is specified, then assume a monorepo layout.
+
+set -e
+
+FILES="ItaniumDemangle.h StringView.h Utility.h README.txt"
+LLVM_DEMANGLE_DIR=$1
+
+if [[ -z "$LLVM_DEMANGLE_DIR" ]]; then
+ LLVM_DEMANGLE_DIR="../../../llvm/include/llvm/Demangle"
+fi
+
+if [[ ! -d "$LLVM_DEMANGLE_DIR" ]]; then
+ echo "No such directory: $LLVM_DEMANGLE_DIR" >&2
+ exit 1
+fi
+
+read -p "This will overwrite the copies of $FILES in $LLVM_DEMANGLE_DIR; are you sure? [y/N]" -n 1 -r ANSWER
+echo
+
+if [[ $ANSWER =~ ^[Yy]$ ]]; then
+ for I in $FILES ; do
+ cp $I $LLVM_DEMANGLE_DIR/$I
+ done
+fi
diff --git a/llvm/include/llvm/Demangle/Compiler.h b/llvm/include/llvm/Demangle/DemangleConfig.h
index 248d6e3a7fa..beaf9a0bf06 100644
--- a/llvm/include/llvm/Demangle/Compiler.h
+++ b/llvm/include/llvm/Demangle/DemangleConfig.h
@@ -1,14 +1,16 @@
-//===--- Compiler.h ---------------------------------------------*- C++ -*-===//
+//===--- DemangleConfig.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
+//===----------------------------------------------------------------------===//
//
// This file contains a variety of feature test macros copied from
// include/llvm/Support/Compiler.h so that LLVMDemangle does not need to take
// a dependency on LLVMSupport.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_COMPILER_H
@@ -37,57 +39,60 @@
#define __has_builtin(x) 0
#endif
-#ifndef LLVM_GNUC_PREREQ
+#ifndef DEMANGLE_GNUC_PREREQ
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
-#define LLVM_GNUC_PREREQ(maj, min, patch) \
+#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
((maj) << 20) + ((min) << 10) + (patch))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
-#define LLVM_GNUC_PREREQ(maj, min, patch) \
+#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
#else
-#define LLVM_GNUC_PREREQ(maj, min, patch) 0
+#define DEMANGLE_GNUC_PREREQ(maj, min, patch) 0
#endif
#endif
-#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
-#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
+#if __has_attribute(used) || DEMANGLE_GNUC_PREREQ(3, 1, 0)
+#define DEMANGLE_ATTRIBUTE_USED __attribute__((__used__))
#else
-#define LLVM_ATTRIBUTE_USED
+#define DEMANGLE_ATTRIBUTE_USED
#endif
-#if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0)
-#define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
+#if __has_builtin(__builtin_unreachable) || DEMANGLE_GNUC_PREREQ(4, 5, 0)
+#define DEMANGLE_UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER)
-#define LLVM_BUILTIN_UNREACHABLE __assume(false)
+#define DEMANGLE_BUILTIN_UNREACHABLE __assume(false)
#endif
-#if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
-#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
+#if __has_attribute(noinline) || DEMANGLE_GNUC_PREREQ(3, 4, 0)
+#define DEMANGLE_ATTRIBUTE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
-#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
+#define DEMANGLE_ATTRIBUTE_NOINLINE __declspec(noinline)
#else
-#define LLVM_ATTRIBUTE_NOINLINE
+#define DEMANGLE_ATTRIBUTE_NOINLINE
#endif
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
+#if !defined(NDEBUG)
+#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE DEMANGLE_ATTRIBUTE_USED
#else
-#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
+#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE
#endif
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
-#define LLVM_FALLTHROUGH [[fallthrough]]
+#define DEMANGLE_FALLTHROUGH [[fallthrough]]
#elif __has_cpp_attribute(gnu::fallthrough)
-#define LLVM_FALLTHROUGH [[gnu::fallthrough]]
+#define DEMANGLE_FALLTHROUGH [[gnu::fallthrough]]
#elif !__cplusplus
// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
// error when __has_cpp_attribute is given a scoped attribute in C mode.
-#define LLVM_FALLTHROUGH
+#define DEMANGLE_FALLTHROUGH
#elif __has_cpp_attribute(clang::fallthrough)
-#define LLVM_FALLTHROUGH [[clang::fallthrough]]
+#define DEMANGLE_FALLTHROUGH [[clang::fallthrough]]
#else
-#define LLVM_FALLTHROUGH
+#define DEMANGLE_FALLTHROUGH
#endif
+#define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle {
+#define DEMANGLE_NAMESPACE_END } }
+
#endif
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 0b9187f30a5..53107c9c8d9 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -6,18 +6,22 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// Generic itanium demangler library. This file has two byte-per-byte identical
+// copies in the source tree, one in libcxxabi, and the other in llvm.
+//
+//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEMANGLE_ITANIUMDEMANGLE_H
-#define LLVM_DEMANGLE_ITANIUMDEMANGLE_H
+#ifndef DEMANGLE_ITANIUMDEMANGLE_H
+#define DEMANGLE_ITANIUMDEMANGLE_H
// FIXME: (possibly) incomplete list of features that clang mangles that this
// file does not yet support:
// - C++ modules TS
-#include "llvm/Demangle/Compiler.h"
-#include "llvm/Demangle/StringView.h"
-#include "llvm/Demangle/Utility.h"
-
+#include "DemangleConfig.h"
+#include "StringView.h"
+#include "Utility.h"
#include <cassert>
#include <cctype>
#include <cstdio>
@@ -95,8 +99,8 @@
X(BracedExpr) \
X(BracedRangeExpr)
-namespace llvm {
-namespace itanium_demangle {
+DEMANGLE_NAMESPACE_BEGIN
+
// Base class of all AST nodes. The AST is built by the parser, then is
// traversed by the printLeft/Right functions to produce a demangled string.
class Node {
@@ -194,7 +198,7 @@ public:
virtual ~Node() = default;
#ifndef NDEBUG
- LLVM_DUMP_METHOD void dump() const;
+ DEMANGLE_DUMP_METHOD void dump() const;
#endif
};
@@ -1278,7 +1282,7 @@ public:
case SpecialSubKind::iostream:
return StringView("basic_iostream");
}
- LLVM_BUILTIN_UNREACHABLE;
+ DEMANGLE_UNREACHABLE;
}
void printLeft(OutputStream &S) const override {
@@ -1330,7 +1334,7 @@ public:
case SpecialSubKind::iostream:
return StringView("iostream");
}
- LLVM_BUILTIN_UNREACHABLE;
+ DEMANGLE_UNREACHABLE;
}
void printLeft(OutputStream &S) const override {
@@ -3467,7 +3471,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
Result = getDerived().parseFunctionType();
break;
}
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
}
case 'U': {
Result = getDerived().parseQualifiedType();
@@ -3754,7 +3758,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
// substitution table.
return Sub;
}
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
}
// ::= <class-enum-type>
default: {
@@ -5178,7 +5182,6 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
Alloc>::AbstractManglingParser;
};
-} // namespace itanium_demangle
-} // namespace llvm
+DEMANGLE_NAMESPACE_END
-#endif // LLVM_DEMANGLE_ITANIUMDEMANGLE_H
+#endif // DEMANGLE_ITANIUMDEMANGLE_H
diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangle.h b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
index 97b918fc945..c0b44cc5143 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangle.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
@@ -10,7 +10,7 @@
#ifndef LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
#define LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
-#include "llvm/Demangle/Compiler.h"
+#include "llvm/Demangle/DemangleConfig.h"
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
#include "llvm/Demangle/StringView.h"
#include "llvm/Demangle/Utility.h"
diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
index 9e3478e9fd2..777d15d912f 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
@@ -1,11 +1,31 @@
+//===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AST nodes used in the MSVC demangler.
+//
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
#define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
-#include "llvm/Demangle/Compiler.h"
+#include "llvm/Demangle/DemangleConfig.h"
#include "llvm/Demangle/StringView.h"
#include <array>
+namespace llvm {
+namespace itanium_demangle {
class OutputStream;
+}
+}
+
+using llvm::itanium_demangle::OutputStream;
+using llvm::itanium_demangle::StringView;
namespace llvm {
namespace ms_demangle {
@@ -602,4 +622,4 @@ struct FunctionSymbolNode : public SymbolNode {
} // namespace ms_demangle
} // namespace llvm
-#endif \ No newline at end of file
+#endif
diff --git a/llvm/include/llvm/Demangle/README.txt b/llvm/include/llvm/Demangle/README.txt
new file mode 100644
index 00000000000..514ff6dd16f
--- /dev/null
+++ b/llvm/include/llvm/Demangle/README.txt
@@ -0,0 +1,52 @@
+Itanium Name Demangler Library
+==============================
+
+Introduction
+------------
+
+This directory contains the generic itanium name demangler library. The main
+purpose of the library is to demangle C++ symbols, i.e. convert the string
+"_Z1fv" into "f()". You can also use the CRTP base ManglingParser to perform
+some simple analysis on the mangled name, or (in LLVM) use the opaque
+ItaniumPartialDemangler to query the demangled AST.
+
+Why are there multiple copies of the this library in the source tree?
+---------------------------------------------------------------------
+
+This directory is mirrored between libcxxabi/demangle and
+llvm/include/llvm/Demangle. The simple reason for this is that both projects
+need to demangle symbols, but neither can depend on each other. libcxxabi needs
+the demangler to implement __cxa_demangle, which is part of the itanium ABI
+spec. LLVM needs a copy for a bunch of places, but doesn't want to use the
+system's __cxa_demangle because it a) might not be available (i.e., on Windows),
+and b) probably isn't that up-to-date on the latest language features.
+
+The copy of the demangler in LLVM has some extra stuff that aren't needed in
+libcxxabi (ie, the MSVC demangler, ItaniumPartialDemangler), which depend on the
+shared generic components. Despite these differences, we want to keep the "core"
+generic demangling library identical between both copies to simplify development
+and testing.
+
+If you're working on the generic library, then do the work first in libcxxabi,
+then run the cp-to-llvm.sh script in src/demangle. This script takes as an
+argument the path to llvm, and re-copies the changes you made to libcxxabi over.
+Note that this script just blindly overwrites all changes to the generic library
+in llvm, so be careful.
+
+Because the core demangler needs to work in libcxxabi, everything needs to be
+declared in an anonymous namespace (see DEMANGLE_NAMESPACE_BEGIN), and you can't
+introduce any code that depends on the libcxx dylib.
+
+Hopefully, when LLVM becomes a monorepo, we can de-duplicate this code, and have
+both LLVM and libcxxabi depend on a shared demangler library.
+
+Testing
+-------
+
+The tests are split up between libcxxabi/test/{unit,}test_demangle.cpp, and
+llvm/unittest/Demangle. The llvm directory should only get tests for stuff not
+included in the core library. In the future though, we should probably move all
+the tests to LLVM.
+
+It is also a really good idea to run libFuzzer after non-trivial changes, see
+libcxxabi/fuzz/cxa_demangle_fuzzer.cpp and https://llvm.org/docs/LibFuzzer.html.
diff --git a/llvm/include/llvm/Demangle/StringView.h b/llvm/include/llvm/Demangle/StringView.h
index a89deda694c..9af4e0684ea 100644
--- a/llvm/include/llvm/Demangle/StringView.h
+++ b/llvm/include/llvm/Demangle/StringView.h
@@ -5,18 +5,22 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
+//===----------------------------------------------------------------------===//
+//
+// FIXME: Use std::string_view instead when we support C++17.
//
-// This file contains a limited version of LLVM's StringView class. It is
-// copied here so that LLVMDemangle need not take a dependency on LLVMSupport.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEMANGLE_STRINGVIEW_H
-#define LLVM_DEMANGLE_STRINGVIEW_H
+#ifndef DEMANGLE_STRINGVIEW_H
+#define DEMANGLE_STRINGVIEW_H
+#include "DemangleConfig.h"
#include <algorithm>
#include <cassert>
#include <cstring>
+DEMANGLE_NAMESPACE_BEGIN
+
class StringView {
const char *First;
const char *Last;
@@ -43,7 +47,7 @@ public:
if (FindBegin < size()) {
// Just forward to memchr, which is faster than a hand-rolled loop.
if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
- return static_cast<const char *>(P) - First;
+ return size_t(static_cast<const char *>(P) - First);
}
return npos;
}
@@ -118,4 +122,6 @@ inline bool operator==(const StringView &LHS, const StringView &RHS) {
std::equal(LHS.begin(), LHS.end(), RHS.begin());
}
+DEMANGLE_NAMESPACE_END
+
#endif
diff --git a/llvm/include/llvm/Demangle/Utility.h b/llvm/include/llvm/Demangle/Utility.h
index 1d1601c8163..4d44cd8f5a1 100644
--- a/llvm/include/llvm/Demangle/Utility.h
+++ b/llvm/include/llvm/Demangle/Utility.h
@@ -5,21 +5,24 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
+//===----------------------------------------------------------------------===//
+//
+// Provide some utility classes for use in the demangler(s).
//
-// This file contains several utility classes used by the demangle library.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEMANGLE_UTILITY_H
-#define LLVM_DEMANGLE_UTILITY_H
+#ifndef DEMANGLE_UTILITY_H
+#define DEMANGLE_UTILITY_H
#include "StringView.h"
-
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <limits>
+DEMANGLE_NAMESPACE_BEGIN
+
// Stream that AST nodes write their string representation into after the AST
// has been parsed.
class OutputStream {
@@ -184,4 +187,6 @@ inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
return true;
}
+DEMANGLE_NAMESPACE_END
+
#endif
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index 51ffa0bff7f..9db2f91b5e1 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -18,7 +18,7 @@
#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
-#include "llvm/Demangle/Compiler.h"
+#include "llvm/Demangle/DemangleConfig.h"
#include "llvm/Demangle/StringView.h"
#include "llvm/Demangle/Utility.h"
@@ -265,7 +265,7 @@ Demangler::demangleSpecialTableSymbolNode(StringView &MangledName,
NI->Name = "`RTTI Complete Object Locator'";
break;
default:
- LLVM_BUILTIN_UNREACHABLE;
+ DEMANGLE_UNREACHABLE;
}
QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
SpecialTableSymbolNode *STSN = Arena.alloc<SpecialTableSymbolNode>();
@@ -632,7 +632,7 @@ translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group) {
case FunctionIdentifierCodeGroup::DoubleUnder:
return DoubleUnder[Index];
}
- LLVM_BUILTIN_UNREACHABLE;
+ DEMANGLE_UNREACHABLE;
}
IdentifierNode *
@@ -1188,7 +1188,7 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
switch (MangledName.popFront()) {
case '1':
IsWcharT = true;
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
case '0':
break;
default:
@@ -1255,7 +1255,7 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
Result->Char = CharKind::Char32;
break;
default:
- LLVM_BUILTIN_UNREACHABLE;
+ DEMANGLE_UNREACHABLE;
}
const unsigned NumChars = BytesDecoded / CharBytes;
for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
@@ -2083,15 +2083,15 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
case 'J':
TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
demangleSigned(MangledName);
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
case 'I':
TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
demangleSigned(MangledName);
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
case 'H':
TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
demangleSigned(MangledName);
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
case '1':
break;
default:
@@ -2117,13 +2117,13 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
case 'G':
TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
demangleSigned(MangledName);
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
case 'F':
TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
demangleSigned(MangledName);
TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
demangleSigned(MangledName);
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
case '0':
break;
default:
diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
index 622f8e75e35..e94d23783e1 100644
--- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
-#include "llvm/Demangle/Compiler.h"
+#include "llvm/Demangle/DemangleConfig.h"
#include "llvm/Demangle/Utility.h"
#include <cctype>
#include <string>
diff --git a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp b/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp
index e55dcd76180..24e600a5c46 100644
--- a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp
+++ b/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp
@@ -22,6 +22,7 @@ using namespace llvm;
using llvm::itanium_demangle::ForwardTemplateReference;
using llvm::itanium_demangle::Node;
using llvm::itanium_demangle::NodeKind;
+using llvm::itanium_demangle::StringView;
namespace {
struct FoldingSetNodeIDBuilder {
OpenPOWER on IntegriCloud