From: Erik Pilkington Date: Thu, 17 Jan 2019 20:37:51 +0000 (+0000) Subject: NFC: Make the copies of the demangler byte-for-byte identical X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cc6eedfcf341fb40b6c876ea10cf5db81fb2124f;p=llvm NFC: Make the copies of the demangler byte-for-byte identical With this patch, the copies of the files ItaniumDemangle.h, StringView.h, and Utility.h are kept byte-for-byte in sync between libcxxabi and llvm. All differences (namespaces, fallthrough, and unreachable macros) are defined in each copies' DemanglerConfig.h. This patch also adds a script to copy changes from libcxxabi (cp-to-llvm.sh), and a README.txt explaining the situation. Differential revision: https://reviews.llvm.org/D53538 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351474 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Demangle/Compiler.h b/include/llvm/Demangle/DemangleConfig.h similarity index 54% rename from include/llvm/Demangle/Compiler.h rename to include/llvm/Demangle/DemangleConfig.h index 248d6e3a7fa..beaf9a0bf06 100644 --- a/include/llvm/Demangle/Compiler.h +++ b/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/include/llvm/Demangle/ItaniumDemangle.h b/include/llvm/Demangle/ItaniumDemangle.h index 0b9187f30a5..53107c9c8d9 100644 --- a/include/llvm/Demangle/ItaniumDemangle.h +++ b/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 #include #include @@ -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::parseType() { Result = getDerived().parseFunctionType(); break; } - LLVM_FALLTHROUGH; + DEMANGLE_FALLTHROUGH; } case 'U': { Result = getDerived().parseQualifiedType(); @@ -3754,7 +3758,7 @@ Node *AbstractManglingParser::parseType() { // substitution table. return Sub; } - LLVM_FALLTHROUGH; + DEMANGLE_FALLTHROUGH; } // ::= default: { @@ -5178,7 +5182,6 @@ struct ManglingParser : AbstractManglingParser, Alloc> { Alloc>::AbstractManglingParser; }; -} // namespace itanium_demangle -} // namespace llvm +DEMANGLE_NAMESPACE_END -#endif // LLVM_DEMANGLE_ITANIUMDEMANGLE_H +#endif // DEMANGLE_ITANIUMDEMANGLE_H diff --git a/include/llvm/Demangle/MicrosoftDemangle.h b/include/llvm/Demangle/MicrosoftDemangle.h index 97b918fc945..c0b44cc5143 100644 --- a/include/llvm/Demangle/MicrosoftDemangle.h +++ b/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/include/llvm/Demangle/MicrosoftDemangleNodes.h b/include/llvm/Demangle/MicrosoftDemangleNodes.h index 9e3478e9fd2..777d15d912f 100644 --- a/include/llvm/Demangle/MicrosoftDemangleNodes.h +++ b/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 +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/include/llvm/Demangle/README.txt b/include/llvm/Demangle/README.txt new file mode 100644 index 00000000000..514ff6dd16f --- /dev/null +++ b/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/include/llvm/Demangle/StringView.h b/include/llvm/Demangle/StringView.h index a89deda694c..9af4e0684ea 100644 --- a/include/llvm/Demangle/StringView.h +++ b/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 #include #include +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(P) - First; + return size_t(static_cast(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/include/llvm/Demangle/Utility.h b/include/llvm/Demangle/Utility.h index 1d1601c8163..4d44cd8f5a1 100644 --- a/include/llvm/Demangle/Utility.h +++ b/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 #include #include #include #include +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/lib/Demangle/MicrosoftDemangle.cpp b/lib/Demangle/MicrosoftDemangle.cpp index 51ffa0bff7f..9db2f91b5e1 100644 --- a/lib/Demangle/MicrosoftDemangle.cpp +++ b/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(); @@ -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/lib/Demangle/MicrosoftDemangleNodes.cpp b/lib/Demangle/MicrosoftDemangleNodes.cpp index 622f8e75e35..e94d23783e1 100644 --- a/lib/Demangle/MicrosoftDemangleNodes.cpp +++ b/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 #include diff --git a/lib/Support/ItaniumManglingCanonicalizer.cpp b/lib/Support/ItaniumManglingCanonicalizer.cpp index e55dcd76180..24e600a5c46 100644 --- a/lib/Support/ItaniumManglingCanonicalizer.cpp +++ b/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 {