From 5092df19372bd6957bd43649da43add30777212d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 30 Aug 2023 07:14:22 +0200 Subject: kill demangle --- demangle/CMakeLists.txt | 39 - demangle/demangle.cpp | 15 - demangle/demangle.h | 4 - demangle/third_party/llvm/LICENSE.txt | 279 - .../llvm/include/llvm/Demangle/Compiler.h | 549 -- .../llvm/include/llvm/Demangle/Demangle.h | 133 - .../llvm/include/llvm/Demangle/DemangleConfig.h | 92 - .../llvm/include/llvm/Demangle/ItaniumDemangle.h | 5500 -------------------- .../llvm/include/llvm/Demangle/ItaniumNodes.def | 95 - .../llvm/include/llvm/Demangle/MicrosoftDemangle.h | 276 - .../include/llvm/Demangle/MicrosoftDemangleNodes.h | 629 --- .../llvm/include/llvm/Demangle/StringView.h | 122 - .../llvm/include/llvm/Demangle/Utility.h | 199 - .../third_party/llvm/lib/Demangle/Demangle.cpp | 68 - .../llvm/lib/Demangle/ItaniumDemangle.cpp | 608 --- .../llvm/lib/Demangle/MicrosoftDemangle.cpp | 2368 --------- .../llvm/lib/Demangle/MicrosoftDemangleNodes.cpp | 658 --- 17 files changed, 11634 deletions(-) delete mode 100644 demangle/CMakeLists.txt delete mode 100644 demangle/demangle.cpp delete mode 100644 demangle/demangle.h delete mode 100644 demangle/third_party/llvm/LICENSE.txt delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/Compiler.h delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/Demangle.h delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/DemangleConfig.h delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/ItaniumDemangle.h delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/ItaniumNodes.def delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/MicrosoftDemangle.h delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/StringView.h delete mode 100644 demangle/third_party/llvm/include/llvm/Demangle/Utility.h delete mode 100644 demangle/third_party/llvm/lib/Demangle/Demangle.cpp delete mode 100644 demangle/third_party/llvm/lib/Demangle/ItaniumDemangle.cpp delete mode 100644 demangle/third_party/llvm/lib/Demangle/MicrosoftDemangle.cpp delete mode 100644 demangle/third_party/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp diff --git a/demangle/CMakeLists.txt b/demangle/CMakeLists.txt deleted file mode 100644 index ce3222a4..00000000 --- a/demangle/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -cmake_minimum_required(VERSION 3.18 FATAL_ERROR) -project(demumble CXX) - -set(CMAKE_CXX_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) -set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) -set(CMAKE_CXX_STANDARD 23) -set(CMAKE_CXX_STANDARD_DEFAULT 23) -set(CMAKE_CXX_STANDARD_REQUIRED TRUE) -set(CMAKE_CXX_EXTENSIONS FALSE) - -if (NOT MSVC) - add_compile_options(-Wall -fno-exceptions -fno-rtti) - # 10.9 chosen somewhat arbitrary; it's the first target where clang defaults - # to libc++ and ld64 defaults to stripping __TEXT,__eh_frame. - if (APPLE) - add_compile_options(-mmacosx-version-min=10.9) - else() - add_compile_options(-fno-plt) - endif() - add_compile_options(-Wno-error -Wno-sign-conversion -Wno-unused -Wno-unused-parameter) - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang$") - add_compile_options(-Wno-shorten-64-to-32 -Wno-implicit-int-conversion -Wno-class-varargs -Wno-extra-semi-stmt) - endif() -else() - add_compile_options(-Zc:inline -permissive- -GR-) - add_compile_options(-wd4100 -wd4244 -wd4267) - add_definitions(-D_HAS_EXCEPTIONS=0 -DNOMINMAX -D_USE_MATH_DEFINES=1) - add_definitions(-D_CRT_SECURE_NO_WARNINGS) # The LLVM build sets this. -endif() - -include_directories(SYSTEM third_party/llvm/include) -add_library(demumble STATIC - third_party/llvm/lib/Demangle/Demangle.cpp - third_party/llvm/lib/Demangle/ItaniumDemangle.cpp - third_party/llvm/lib/Demangle/MicrosoftDemangle.cpp - third_party/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp - demangle.cpp) -target_link_libraries(demumble PUBLIC Corrade::Containers) diff --git a/demangle/demangle.cpp b/demangle/demangle.cpp deleted file mode 100644 index f3cfd231..00000000 --- a/demangle/demangle.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "demangle.h" -#include -#include -#include "llvm/Demangle/Demangle.h" - -using namespace Corrade::Containers; - -String demangle_symbol(const char* symbol) -{ - if (!symbol || !*symbol) - return {}; - if (const auto str = llvm::demangle(symbol); !str.empty()) - return String{str.data(), str.size()}; - return {}; -} diff --git a/demangle/demangle.h b/demangle/demangle.h deleted file mode 100644 index 632f9c14..00000000 --- a/demangle/demangle.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -Corrade::Containers::String demangle_symbol(const char* symbol); diff --git a/demangle/third_party/llvm/LICENSE.txt b/demangle/third_party/llvm/LICENSE.txt deleted file mode 100644 index fa6ac540..00000000 --- a/demangle/third_party/llvm/LICENSE.txt +++ /dev/null @@ -1,279 +0,0 @@ -============================================================================== -The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: -============================================================================== - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. - -============================================================================== -Software from third parties included in the LLVM Project: -============================================================================== -The LLVM Project contains third party software which is under different license -terms. All such code will be identified clearly using at least one of two -mechanisms: -1) It will be in a separate directory tree with its own `LICENSE.txt` or - `LICENSE` file at the top containing the specific license and restrictions - which apply to that software, or -2) It will contain specific license and restriction terms at the top of every - file. - -============================================================================== -Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): -============================================================================== -University of Illinois/NCSA -Open Source License - -Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign. -All rights reserved. - -Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - http://llvm.org - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimers. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - * Neither the names of the LLVM Team, University of Illinois at - Urbana-Champaign, nor the names of its contributors may be used to - endorse or promote products derived from this Software without specific - prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - diff --git a/demangle/third_party/llvm/include/llvm/Demangle/Compiler.h b/demangle/third_party/llvm/include/llvm/Demangle/Compiler.h deleted file mode 100644 index c17ff4ca..00000000 --- a/demangle/third_party/llvm/include/llvm/Demangle/Compiler.h +++ /dev/null @@ -1,549 +0,0 @@ -//===--- Compiler.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 -#define LLVM_DEMANGLE_COMPILER_H - -#ifdef __cplusplus -#include -#endif -#include - -#if defined(_MSC_VER) -#include -#endif - -#ifndef __has_feature -# define __has_feature(x) 0 -#endif - -#ifndef __has_extension -# define __has_extension(x) 0 -#endif - -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif - -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -// Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in -// C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid. -#ifndef LLVM_HAS_CPP_ATTRIBUTE -#if defined(__cplusplus) && defined(__has_cpp_attribute) -# define LLVM_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -# define LLVM_HAS_CPP_ATTRIBUTE(x) 0 -#endif -#endif - -/// \macro LLVM_GNUC_PREREQ -/// Extend the default __GNUC_PREREQ even if glibc's features.h isn't -/// available. -#ifndef LLVM_GNUC_PREREQ -# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -# define LLVM_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) \ - ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) -# else -# define LLVM_GNUC_PREREQ(maj, min, patch) 0 -# endif -#endif - -/// \macro LLVM_MSC_PREREQ -/// Is the compiler MSVC of at least the specified version? -/// The common \param version values to check for are: -/// * 1910: VS2017, version 15.1 & 15.2 -/// * 1911: VS2017, version 15.3 & 15.4 -/// * 1912: VS2017, version 15.5 -/// * 1913: VS2017, version 15.6 -/// * 1914: VS2017, version 15.7 -/// * 1915: VS2017, version 15.8 -/// * 1916: VS2017, version 15.9 -/// * 1920: VS2019, version 16.0 -/// * 1921: VS2019, version 16.1 -#ifdef _MSC_VER -#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version)) - -// We require at least MSVC 2017. -#if !LLVM_MSC_PREREQ(1910) -#error LLVM requires at least MSVC 2017. -#endif - -#else -#define LLVM_MSC_PREREQ(version) 0 -#endif - -/// Does the compiler support ref-qualifiers for *this? -/// -/// Sadly, this is separate from just rvalue reference support because GCC -/// and MSVC implemented this later than everything else. This appears to be -/// corrected in MSVC 2019 but not MSVC 2017. -#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1) || \ - LLVM_MSC_PREREQ(1920) -#define LLVM_HAS_RVALUE_REFERENCE_THIS 1 -#else -#define LLVM_HAS_RVALUE_REFERENCE_THIS 0 -#endif - -/// Expands to '&' if ref-qualifiers for *this are supported. -/// -/// This can be used to provide lvalue/rvalue overrides of member functions. -/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS -#if LLVM_HAS_RVALUE_REFERENCE_THIS -#define LLVM_LVALUE_FUNCTION & -#else -#define LLVM_LVALUE_FUNCTION -#endif - -/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked -/// into a shared library, then the class should be private to the library and -/// not accessible from outside it. Can also be used to mark variables and -/// functions, making them private to any shared library they are linked into. -/// On PE/COFF targets, library visibility is the default, so this isn't needed. -/// -/// LLVM_EXTERNAL_VISIBILITY - classes, functions, and variables marked with -/// this attribute will be made public and visible outside of any shared library -/// they are linked in to. -#if (__has_attribute(visibility) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ - !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32) -#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) -#define LLVM_EXTERNAL_VISIBILITY __attribute__ ((visibility("default"))) -#else -#define LLVM_LIBRARY_VISIBILITY -#define LLVM_EXTERNAL_VISIBILITY -#endif - -#if defined(__GNUC__) -#define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality) -#else -#define LLVM_PREFETCH(addr, rw, locality) -#endif - -#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0) -#define LLVM_ATTRIBUTE_USED __attribute__((__used__)) -#else -#define LLVM_ATTRIBUTE_USED -#endif - -/// LLVM_NODISCARD - Warn if a type or return value is discarded. - -// Use the 'nodiscard' attribute in C++17 or newer mode. -#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) -#define LLVM_NODISCARD [[nodiscard]] -#elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result) -#define LLVM_NODISCARD [[clang::warn_unused_result]] -// Clang in C++14 mode claims that it has the 'nodiscard' attribute, but also -// warns in the pedantic mode that 'nodiscard' is a C++17 extension (PR33518). -// Use the 'nodiscard' attribute in C++14 mode only with GCC. -// TODO: remove this workaround when PR33518 is resolved. -#elif defined(__GNUC__) && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) -#define LLVM_NODISCARD [[nodiscard]] -#else -#define LLVM_NODISCARD -#endif - -// Indicate that a non-static, non-const C++ member function reinitializes -// the entire object to a known state, independent of the previous state of -// the object. -// -// The clang-tidy check bugprone-use-after-move recognizes this attribute as a -// marker that a moved-from object has left the indeterminate state and can be -// reused. -#if LLVM_HAS_CPP_ATTRIBUTE(clang::reinitializes) -#define LLVM_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] -#else -#define LLVM_ATTRIBUTE_REINITIALIZES -#endif - -// Some compilers warn about unused functions. When a function is sometimes -// used or not depending on build settings (e.g. a function only called from -// within "assert"), this attribute can be used to suppress such warnings. -// -// However, it shouldn't be used for unused *variables*, as those have a much -// more portable solution: -// (void)unused_var_name; -// Prefer cast-to-void wherever it is sufficient. -#if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0) -#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) -#else -#define LLVM_ATTRIBUTE_UNUSED -#endif - -// FIXME: Provide this for PE/COFF targets. -#if (__has_attribute(weak) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ - (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32)) -#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) -#else -#define LLVM_ATTRIBUTE_WEAK -#endif - -// Prior to clang 3.2, clang did not accept any spelling of -// __has_attribute(const), so assume it is supported. -#if defined(__clang__) || defined(__GNUC__) -// aka 'CONST' but following LLVM Conventions. -#define LLVM_READNONE __attribute__((__const__)) -#else -#define LLVM_READNONE -#endif - -#if __has_attribute(pure) || defined(__GNUC__) -// aka 'PURE' but following LLVM Conventions. -#define LLVM_READONLY __attribute__((__pure__)) -#else -#define LLVM_READONLY -#endif - -#if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0) -#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) -#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) -#else -#define LLVM_LIKELY(EXPR) (EXPR) -#define LLVM_UNLIKELY(EXPR) (EXPR) -#endif - -/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, -/// mark a method "not for inlining". -#if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0) -#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) -#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) -#else -#define LLVM_ATTRIBUTE_NOINLINE -#endif - -/// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do -/// so, mark a method "always inline" because it is performance sensitive. GCC -/// 3.4 supported this but is buggy in various cases and produces unimplemented -/// errors, just use it in GCC 4.0 and later. -#if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0) -#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) -#elif defined(_MSC_VER) -#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline -#else -#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline -#endif - -#ifdef __GNUC__ -#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn)) -#elif defined(_MSC_VER) -#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn) -#else -#define LLVM_ATTRIBUTE_NORETURN -#endif - -#if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0) -#define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) -#elif defined(_MSC_VER) -#define LLVM_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_ -#else -#define LLVM_ATTRIBUTE_RETURNS_NONNULL -#endif - -/// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a -/// pointer that does not alias any other valid pointer. -#ifdef __GNUC__ -#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__)) -#elif defined(_MSC_VER) -#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict) -#else -#define LLVM_ATTRIBUTE_RETURNS_NOALIAS -#endif - -/// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements. -#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough) -#define LLVM_FALLTHROUGH [[fallthrough]] -#elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough) -#define LLVM_FALLTHROUGH [[gnu::fallthrough]] -#elif __has_attribute(fallthrough) -#define LLVM_FALLTHROUGH __attribute__((fallthrough)) -#elif LLVM_HAS_CPP_ATTRIBUTE(clang::fallthrough) -#define LLVM_FALLTHROUGH [[clang::fallthrough]] -#else -#define LLVM_FALLTHROUGH -#endif - -/// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that -/// they are constant initialized. -#if LLVM_HAS_CPP_ATTRIBUTE(clang::require_constant_initialization) -#define LLVM_REQUIRE_CONSTANT_INITIALIZATION \ - [[clang::require_constant_initialization]] -#else -#define LLVM_REQUIRE_CONSTANT_INITIALIZATION -#endif - -/// LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable -/// lifetime warnings. -#if LLVM_HAS_CPP_ATTRIBUTE(gsl::Owner) -#define LLVM_GSL_OWNER [[gsl::Owner]] -#else -#define LLVM_GSL_OWNER -#endif - -/// LLVM_GSL_POINTER - Apply this to non-owning classes like -/// StringRef to enable lifetime warnings. -#if LLVM_HAS_CPP_ATTRIBUTE(gsl::Pointer) -#define LLVM_GSL_POINTER [[gsl::Pointer]] -#else -#define LLVM_GSL_POINTER -#endif - -/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress -/// pedantic diagnostics. -#ifdef __GNUC__ -#define LLVM_EXTENSION __extension__ -#else -#define LLVM_EXTENSION -#endif - -// LLVM_ATTRIBUTE_DEPRECATED(decl, "message") -// This macro will be removed. -// Use C++14's attribute instead: [[deprecated("message")]] -#define LLVM_ATTRIBUTE_DEPRECATED(decl, message) [[deprecated(message)]] decl - -/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands -/// to an expression which states that it is undefined behavior for the -/// compiler to reach this point. Otherwise is not defined. -#if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0) -# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() -#elif defined(_MSC_VER) -# define LLVM_BUILTIN_UNREACHABLE __assume(false) -#endif - -/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression -/// which causes the program to exit abnormally. -#if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0) -# define LLVM_BUILTIN_TRAP __builtin_trap() -#elif defined(_MSC_VER) -// The __debugbreak intrinsic is supported by MSVC, does not require forward -// declarations involving platform-specific typedefs (unlike RaiseException), -// results in a call to vectored exception handlers, and encodes to a short -// instruction that still causes the trapping behavior we want. -# define LLVM_BUILTIN_TRAP __debugbreak() -#else -# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 -#endif - -/// LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to -/// an expression which causes the program to break while running -/// under a debugger. -#if __has_builtin(__builtin_debugtrap) -# define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap() -#elif defined(_MSC_VER) -// The __debugbreak intrinsic is supported by MSVC and breaks while -// running under the debugger, and also supports invoking a debugger -// when the OS is configured appropriately. -# define LLVM_BUILTIN_DEBUGTRAP __debugbreak() -#else -// Just continue execution when built with compilers that have no -// support. This is a debugging aid and not intended to force the -// program to abort if encountered. -# define LLVM_BUILTIN_DEBUGTRAP -#endif - -/// \macro LLVM_ASSUME_ALIGNED -/// Returns a pointer with an assumed alignment. -#if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0) -# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) -#elif defined(LLVM_BUILTIN_UNREACHABLE) -# define LLVM_ASSUME_ALIGNED(p, a) \ - (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p))) -#else -# define LLVM_ASSUME_ALIGNED(p, a) (p) -#endif - -/// \macro LLVM_PACKED -/// Used to specify a packed structure. -/// LLVM_PACKED( -/// struct A { -/// int i; -/// int j; -/// int k; -/// long long l; -/// }); -/// -/// LLVM_PACKED_START -/// struct B { -/// int i; -/// int j; -/// int k; -/// long long l; -/// }; -/// LLVM_PACKED_END -#ifdef _MSC_VER -# define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop)) -# define LLVM_PACKED_START __pragma(pack(push, 1)) -# define LLVM_PACKED_END __pragma(pack(pop)) -#else -# define LLVM_PACKED(d) d __attribute__((packed)) -# define LLVM_PACKED_START _Pragma("pack(push, 1)") -# define LLVM_PACKED_END _Pragma("pack(pop)") -#endif - -/// \macro LLVM_PTR_SIZE -/// A constant integer equivalent to the value of sizeof(void*). -/// Generally used in combination with alignas or when doing computation in the -/// preprocessor. -#ifdef __SIZEOF_POINTER__ -# define LLVM_PTR_SIZE __SIZEOF_POINTER__ -#elif defined(_WIN64) -# define LLVM_PTR_SIZE 8 -#elif defined(_WIN32) -# define LLVM_PTR_SIZE 4 -#elif defined(_MSC_VER) -# error "could not determine LLVM_PTR_SIZE as a constant int for MSVC" -#else -# define LLVM_PTR_SIZE sizeof(void *) -#endif - -/// \macro LLVM_MEMORY_SANITIZER_BUILD -/// Whether LLVM itself is built with MemorySanitizer instrumentation. -#if __has_feature(memory_sanitizer) -# define LLVM_MEMORY_SANITIZER_BUILD 1 -# include -# define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE __attribute__((no_sanitize_memory)) -#else -# define LLVM_MEMORY_SANITIZER_BUILD 0 -# define __msan_allocated_memory(p, size) -# define __msan_unpoison(p, size) -# define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE -#endif - -/// \macro LLVM_ADDRESS_SANITIZER_BUILD -/// Whether LLVM itself is built with AddressSanitizer instrumentation. -#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) -# define LLVM_ADDRESS_SANITIZER_BUILD 1 -# include -#else -# define LLVM_ADDRESS_SANITIZER_BUILD 0 -# define __asan_poison_memory_region(p, size) -# define __asan_unpoison_memory_region(p, size) -#endif - -/// \macro LLVM_THREAD_SANITIZER_BUILD -/// Whether LLVM itself is built with ThreadSanitizer instrumentation. -#if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__) -# define LLVM_THREAD_SANITIZER_BUILD 1 -#else -# define LLVM_THREAD_SANITIZER_BUILD 0 -#endif - -#if LLVM_THREAD_SANITIZER_BUILD -// Thread Sanitizer is a tool that finds races in code. -// See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations . -// tsan detects these exact functions by name. -#ifdef __cplusplus -extern "C" { -#endif -void AnnotateHappensAfter(const char *file, int line, const volatile void *cv); -void AnnotateHappensBefore(const char *file, int line, const volatile void *cv); -void AnnotateIgnoreWritesBegin(const char *file, int line); -void AnnotateIgnoreWritesEnd(const char *file, int line); -#ifdef __cplusplus -} -#endif - -// This marker is used to define a happens-before arc. The race detector will -// infer an arc from the begin to the end when they share the same pointer -// argument. -# define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv) - -// This marker defines the destination of a happens-before arc. -# define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv) - -// Ignore any races on writes between here and the next TsanIgnoreWritesEnd. -# define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__) - -// Resume checking for racy writes. -# define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__) -#else -# define TsanHappensBefore(cv) -# define TsanHappensAfter(cv) -# define TsanIgnoreWritesBegin() -# define TsanIgnoreWritesEnd() -#endif - -/// \macro LLVM_NO_SANITIZE -/// Disable a particular sanitizer for a function. -#if __has_attribute(no_sanitize) -#define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND))) -#else -#define LLVM_NO_SANITIZE(KIND) -#endif - -/// Mark debug helper function definitions like dump() that should not be -/// stripped from debug builds. -/// Note that you should also surround dump() functions with -/// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always -/// get stripped in release builds. -// FIXME: Move this to a private config.h as it's not usable in public headers. -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED -#else -#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE -#endif - -/// \macro LLVM_PRETTY_FUNCTION -/// Gets a user-friendly looking function signature for the current scope -/// using the best available method on each platform. The exact format of the -/// resulting string is implementation specific and non-portable, so this should -/// only be used, for example, for logging or diagnostics. -#if defined(_MSC_VER) -#define LLVM_PRETTY_FUNCTION __FUNCSIG__ -#elif defined(__GNUC__) || defined(__clang__) -#define LLVM_PRETTY_FUNCTION __PRETTY_FUNCTION__ -#else -#define LLVM_PRETTY_FUNCTION __func__ -#endif - -/// \macro LLVM_THREAD_LOCAL -/// A thread-local storage specifier which can be used with globals, -/// extern globals, and static globals. -/// -/// This is essentially an extremely restricted analog to C++11's thread_local -/// support. It uses thread_local if available, falling back on gcc __thread -/// if not. __thread doesn't support many of the C++11 thread_local's -/// features. You should only use this for PODs that you can statically -/// initialize to some constant value. In almost all circumstances this is most -/// appropriate for use with a pointer, integer, or small aggregation of -/// pointers and integers. -#if LLVM_ENABLE_THREADS -#if __has_feature(cxx_thread_local) || defined(_MSC_VER) -#define LLVM_THREAD_LOCAL thread_local -#else -// Clang, GCC, and other compatible compilers used __thread prior to C++11 and -// we only need the restricted functionality that provides. -#define LLVM_THREAD_LOCAL __thread -#endif -#else // !LLVM_ENABLE_THREADS -// If threading is disabled entirely, this compiles to nothing and you get -// a normal global variable. -#define LLVM_THREAD_LOCAL -#endif - -/// \macro LLVM_ENABLE_EXCEPTIONS -/// Whether LLVM is built with exception support. -#if __has_feature(cxx_exceptions) -#define LLVM_ENABLE_EXCEPTIONS 1 -#elif defined(__GNUC__) && defined(__EXCEPTIONS) -#define LLVM_ENABLE_EXCEPTIONS 1 -#elif defined(_MSC_VER) && defined(_CPPUNWIND) -#define LLVM_ENABLE_EXCEPTIONS 1 -#endif - -#endif diff --git a/demangle/third_party/llvm/include/llvm/Demangle/Demangle.h b/demangle/third_party/llvm/include/llvm/Demangle/Demangle.h deleted file mode 100644 index 6133d0b9..00000000 --- a/demangle/third_party/llvm/include/llvm/Demangle/Demangle.h +++ /dev/null @@ -1,133 +0,0 @@ -//===--- Demangle.h ---------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEMANGLE_DEMANGLE_H -#define LLVM_DEMANGLE_DEMANGLE_H - -#include -#include - -namespace llvm { -/// This is a llvm local version of __cxa_demangle. Other than the name and -/// being in the llvm namespace it is identical. -/// -/// The mangled_name is demangled into buf and returned. If the buffer is not -/// large enough, realloc is used to expand it. -/// -/// The *status will be set to a value from the following enumeration -enum : int { - demangle_unknown_error = -4, - demangle_invalid_args = -3, - demangle_invalid_mangled_name = -2, - demangle_memory_alloc_failure = -1, - demangle_success = 0, -}; - -char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n, - int *status); - -enum MSDemangleFlags { - MSDF_None = 0, - MSDF_DumpBackrefs = 1 << 0, - MSDF_NoAccessSpecifier = 1 << 1, - MSDF_NoCallingConvention = 1 << 2, - MSDF_NoReturnType = 1 << 3, - MSDF_NoMemberType = 1 << 4, - MSDF_NoVariableType = 1 << 5, -}; - -/// Demangles the Microsoft symbol pointed at by mangled_name and returns it. -/// Returns a pointer to the start of a null-terminated demangled string on -/// success, or nullptr on error. -/// If n_read is non-null and demangling was successful, it receives how many -/// bytes of the input string were consumed. -/// buf can point to a *n_buf bytes large buffer where the demangled name is -/// stored. If the buffer is too small, it is grown with realloc(). If buf is -/// nullptr, then this malloc()s memory for the result. -/// *n_buf stores the size of buf on input if buf is non-nullptr, and it -/// receives the size of the demangled string on output if n_buf is not nullptr. -/// status receives one of the demangle_ enum entries above if it's not nullptr. -/// Flags controls various details of the demangled representation. -char *microsoftDemangle(const char *mangled_name, size_t *n_read, char *buf, - size_t *n_buf, int *status, - MSDemangleFlags Flags = MSDF_None); - -// Demangles a Rust v0 mangled symbol. -char *rustDemangle(const char *MangledName); - -// Demangles a D mangled symbol. -char *dlangDemangle(const char *MangledName); - -/// Attempt to demangle a string using different demangling schemes. -/// The function uses heuristics to determine which demangling scheme to use. -/// \param MangledName - reference to string to demangle. -/// \returns - the demangled string, or a copy of the input string if no -/// demangling occurred. -std::string demangle(const std::string &MangledName); - -bool nonMicrosoftDemangle(const char *MangledName, std::string &Result); - -/// "Partial" demangler. This supports demangling a string into an AST -/// (typically an intermediate stage in itaniumDemangle) and querying certain -/// properties or partially printing the demangled name. -struct ItaniumPartialDemangler { - ItaniumPartialDemangler(); - - ItaniumPartialDemangler(ItaniumPartialDemangler &&Other); - ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other); - - /// Demangle into an AST. Subsequent calls to the rest of the member functions - /// implicitly operate on the AST this produces. - /// \return true on error, false otherwise - bool partialDemangle(const char *MangledName); - - /// Just print the entire mangled name into Buf. Buf and N behave like the - /// second and third parameters to itaniumDemangle. - char *finishDemangle(char *Buf, size_t *N) const; - - /// Get the base name of a function. This doesn't include trailing template - /// arguments, ie for "a::b" this function returns "b". - char *getFunctionBaseName(char *Buf, size_t *N) const; - - /// Get the context name for a function. For "a::b::c", this function returns - /// "a::b". - char *getFunctionDeclContextName(char *Buf, size_t *N) const; - - /// Get the entire name of this function. - char *getFunctionName(char *Buf, size_t *N) const; - - /// Get the parameters for this function. - char *getFunctionParameters(char *Buf, size_t *N) const; - char *getFunctionReturnType(char *Buf, size_t *N) const; - - /// If this function has any any cv or reference qualifiers. These imply that - /// the function is a non-static member function. - bool hasFunctionQualifiers() const; - - /// If this symbol describes a constructor or destructor. - bool isCtorOrDtor() const; - - /// If this symbol describes a function. - bool isFunction() const; - - /// If this symbol describes a variable. - bool isData() const; - - /// If this symbol is a . These are generally implicitly - /// generated by the implementation, such as vtables and typeinfo names. - bool isSpecialName() const; - - ~ItaniumPartialDemangler(); - -private: - void *RootNode; - void *Context; -}; -} // namespace llvm - -#endif diff --git a/demangle/third_party/llvm/include/llvm/Demangle/DemangleConfig.h b/demangle/third_party/llvm/include/llvm/Demangle/DemangleConfig.h deleted file mode 100644 index 2ff95dd8..00000000 --- a/demangle/third_party/llvm/include/llvm/Demangle/DemangleConfig.h +++ /dev/null @@ -1,92 +0,0 @@ -//===--- DemangleConfig.h ---------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// 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_DEMANGLECONFIG_H -#define LLVM_DEMANGLE_DEMANGLECONFIG_H - -#ifndef __has_feature -#define __has_feature(x) 0 -#endif - -#ifndef __has_cpp_attribute -#define __has_cpp_attribute(x) 0 -#endif - -#ifndef __has_attribute -#define __has_attribute(x) 0 -#endif - -#ifndef __has_builtin -#define __has_builtin(x) 0 -#endif - -#ifndef DEMANGLE_GNUC_PREREQ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -#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 DEMANGLE_GNUC_PREREQ(maj, min, patch) \ - ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) -#else -#define DEMANGLE_GNUC_PREREQ(maj, min, patch) 0 -#endif -#endif - -#if __has_attribute(used) || DEMANGLE_GNUC_PREREQ(3, 1, 0) -#define DEMANGLE_ATTRIBUTE_USED __attribute__((__used__)) -#else -#define DEMANGLE_ATTRIBUTE_USED -#endif - -#if __has_builtin(__builtin_unreachable) || DEMANGLE_GNUC_PREREQ(4, 5, 0) -#define DEMANGLE_UNREACHABLE __builtin_unreachable() -#elif defined(_MSC_VER) -#define DEMANGLE_UNREACHABLE __assume(false) -#else -#define DEMANGLE_UNREACHABLE -#endif - -#if __has_attribute(noinline) || DEMANGLE_GNUC_PREREQ(3, 4, 0) -#define DEMANGLE_ATTRIBUTE_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) -#define DEMANGLE_ATTRIBUTE_NOINLINE __declspec(noinline) -#else -#define DEMANGLE_ATTRIBUTE_NOINLINE -#endif - -#if !defined(NDEBUG) -#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE DEMANGLE_ATTRIBUTE_USED -#else -#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE -#endif - -#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough) -#define DEMANGLE_FALLTHROUGH [[fallthrough]] -#elif __has_cpp_attribute(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 DEMANGLE_FALLTHROUGH -#elif __has_cpp_attribute(clang::fallthrough) -#define DEMANGLE_FALLTHROUGH [[clang::fallthrough]] -#else -#define DEMANGLE_FALLTHROUGH -#endif - -#define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle { -#define DEMANGLE_NAMESPACE_END } } - -#endif diff --git a/demangle/third_party/llvm/include/llvm/Demangle/ItaniumDemangle.h b/demangle/third_party/llvm/include/llvm/Demangle/ItaniumDemangle.h deleted file mode 100644 index ea55f4a6..00000000 --- a/demangle/third_party/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ /dev/null @@ -1,5500 +0,0 @@ -//===--- ItaniumDemangle.h -----------*- mode:c++;eval:(read-only-mode) -*-===// -// Do not edit! See README.txt. -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Generic itanium demangler library. -// There are two copies of this file in the source tree. The one under -// libcxxabi is the original and the one under llvm is the copy. Use -// cp-to-llvm.sh to update the copy. See README.txt for more details. -// -//===----------------------------------------------------------------------===// - -#ifndef DEMANGLE_ITANIUMDEMANGLE_H -#define DEMANGLE_ITANIUMDEMANGLE_H - -#include "DemangleConfig.h" -#include "StringView.h" -#include "Utility.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DEMANGLE_NAMESPACE_BEGIN - -template class PODSmallVector { - static_assert(std::is_pod::value, - "T is required to be a plain old data type"); - - T *First = nullptr; - T *Last = nullptr; - T *Cap = nullptr; - T Inline[N] = {0}; - - bool isInline() const { return First == Inline; } - - void clearInline() { - First = Inline; - Last = Inline; - Cap = Inline + N; - } - - void reserve(size_t NewCap) { - size_t S = size(); - if (isInline()) { - auto *Tmp = static_cast(std::malloc(NewCap * sizeof(T))); - if (Tmp == nullptr) - std::terminate(); - std::copy(First, Last, Tmp); - First = Tmp; - } else { - First = static_cast(std::realloc(First, NewCap * sizeof(T))); - if (First == nullptr) - std::terminate(); - } - Last = First + S; - Cap = First + NewCap; - } - -public: - PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {} - - PODSmallVector(const PODSmallVector &) = delete; - PODSmallVector &operator=(const PODSmallVector &) = delete; - - PODSmallVector(PODSmallVector &&Other) : PODSmallVector() { - if (Other.isInline()) { - std::copy(Other.begin(), Other.end(), First); - Last = First + Other.size(); - Other.clear(); - return; - } - - First = Other.First; - Last = Other.Last; - Cap = Other.Cap; - Other.clearInline(); - } - - PODSmallVector &operator=(PODSmallVector &&Other) { - if (Other.isInline()) { - if (!isInline()) { - std::free(First); - clearInline(); - } - std::copy(Other.begin(), Other.end(), First); - Last = First + Other.size(); - Other.clear(); - return *this; - } - - if (isInline()) { - First = Other.First; - Last = Other.Last; - Cap = Other.Cap; - Other.clearInline(); - return *this; - } - - std::swap(First, Other.First); - std::swap(Last, Other.Last); - std::swap(Cap, Other.Cap); - Other.clear(); - return *this; - } - - // NOLINTNEXTLINE(readability-identifier-naming) - void push_back(const T &Elem) { - if (Last == Cap) - reserve(size() * 2); - *Last++ = Elem; - } - - // NOLINTNEXTLINE(readability-identifier-naming) - void pop_back() { - assert(Last != First && "Popping empty vector!"); - --Last; - } - - void dropBack(size_t Index) { - assert(Index <= size() && "dropBack() can't expand!"); - Last = First + Index; - } - - T *begin() { return First; } - T *end() { return Last; } - - bool empty() const { return First == Last; } - size_t size() const { return static_cast(Last - First); } - T &back() { - assert(Last != First && "Calling back() on empty vector!"); - return *(Last - 1); - } - T &operator[](size_t Index) { - assert(Index < size() && "Invalid access!"); - return *(begin() + Index); - } - void clear() { Last = First; } - - ~PODSmallVector() { - if (!isInline()) - std::free(First); - } -}; - -// 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 { -public: - enum Kind : unsigned char { -#define NODE(NodeKind) K##NodeKind, -#include "ItaniumNodes.def" - }; - - /// Three-way bool to track a cached value. Unknown is possible if this node - /// has an unexpanded parameter pack below it that may affect this cache. - enum class Cache : unsigned char { Yes, No, Unknown, }; - - /// Operator precedence for expression nodes. Used to determine required - /// parens in expression emission. - enum class Prec { - Primary, - Postfix, - Unary, - Cast, - PtrMem, - Multiplicative, - Additive, - Shift, - Spaceship, - Relational, - Equality, - And, - Xor, - Ior, - AndIf, - OrIf, - Conditional, - Assign, - Comma, - Default, - }; - -private: - Kind K; - - Prec Precedence : 6; - - // FIXME: Make these protected. -public: - /// Tracks if this node has a component on its right side, in which case we - /// need to call printRight. - Cache RHSComponentCache : 2; - - /// Track if this node is a (possibly qualified) array type. This can affect - /// how we format the output string. - Cache ArrayCache : 2; - - /// Track if this node is a (possibly qualified) function type. This can - /// affect how we format the output string. - Cache FunctionCache : 2; - -public: - Node(Kind K_, Prec Precedence_ = Prec::Primary, - Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No, - Cache FunctionCache_ = Cache::No) - : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_), - ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {} - Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No, - Cache FunctionCache_ = Cache::No) - : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_, - FunctionCache_) {} - - /// Visit the most-derived object corresponding to this object. - template void visit(Fn F) const; - - // The following function is provided by all derived classes: - // - // Call F with arguments that, when passed to the constructor of this node, - // would construct an equivalent node. - //template void match(Fn F) const; - - bool hasRHSComponent(OutputBuffer &OB) const { - if (RHSComponentCache != Cache::Unknown) - return RHSComponentCache == Cache::Yes; - return hasRHSComponentSlow(OB); - } - - bool hasArray(OutputBuffer &OB) const { - if (ArrayCache != Cache::Unknown) - return ArrayCache == Cache::Yes; - return hasArraySlow(OB); - } - - bool hasFunction(OutputBuffer &OB) const { - if (FunctionCache != Cache::Unknown) - return FunctionCache == Cache::Yes; - return hasFunctionSlow(OB); - } - - Kind getKind() const { return K; } - - Prec getPrecedence() const { return Precedence; } - - virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; } - virtual bool hasArraySlow(OutputBuffer &) const { return false; } - virtual bool hasFunctionSlow(OutputBuffer &) const { return false; } - - // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to - // get at a node that actually represents some concrete syntax. - virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; } - - // Print this node as an expression operand, surrounding it in parentheses if - // its precedence is [Strictly] weaker than P. - void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default, - bool StrictlyWorse = false) const { - bool Paren = - unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse); - if (Paren) - OB.printOpen(); - print(OB); - if (Paren) - OB.printClose(); - } - - void print(OutputBuffer &OB) const { - printLeft(OB); - if (RHSComponentCache != Cache::No) - printRight(OB); - } - - // Print the "left" side of this Node into OutputBuffer. - virtual void printLeft(OutputBuffer &) const = 0; - - // Print the "right". This distinction is necessary to represent C++ types - // that appear on the RHS of their subtype, such as arrays or functions. - // Since most types don't have such a component, provide a default - // implementation. - virtual void printRight(OutputBuffer &) const {} - - virtual StringView getBaseName() const { return StringView(); } - - // Silence compiler warnings, this dtor will never be called. - virtual ~Node() = default; - -#ifndef NDEBUG - DEMANGLE_DUMP_METHOD void dump() const; -#endif -}; - -class NodeArray { - Node **Elements; - size_t NumElements; - -public: - NodeArray() : Elements(nullptr), NumElements(0) {} - NodeArray(Node **Elements_, size_t NumElements_) - : Elements(Elements_), NumElements(NumElements_) {} - - bool empty() const { return NumElements == 0; } - size_t size() const { return NumElements; } - - Node **begin() const { return Elements; } - Node **end() const { return Elements + NumElements; } - - Node *operator[](size_t Idx) const { return Elements[Idx]; } - - void printWithComma(OutputBuffer &OB) const { - bool FirstElement = true; - for (size_t Idx = 0; Idx != NumElements; ++Idx) { - size_t BeforeComma = OB.getCurrentPosition(); - if (!FirstElement) - OB += ", "; - size_t AfterComma = OB.getCurrentPosition(); - Elements[Idx]->printAsOperand(OB, Node::Prec::Comma); - - // Elements[Idx] is an empty parameter pack expansion, we should erase the - // comma we just printed. - if (AfterComma == OB.getCurrentPosition()) { - OB.setCurrentPosition(BeforeComma); - continue; - } - - FirstElement = false; - } - } -}; - -struct NodeArrayNode : Node { - NodeArray Array; - NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {} - - template void match(Fn F) const { F(Array); } - - void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); } -}; - -class DotSuffix final : public Node { - const Node *Prefix; - const StringView Suffix; - -public: - DotSuffix(const Node *Prefix_, StringView Suffix_) - : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {} - - template void match(Fn F) const { F(Prefix, Suffix); } - - void printLeft(OutputBuffer &OB) const override { - Prefix->print(OB); - OB += " ("; - OB += Suffix; - OB += ")"; - } -}; - -class VendorExtQualType final : public Node { - const Node *Ty; - StringView Ext; - const Node *TA; - -public: - VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_) - : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {} - - const Node *getTy() const { return Ty; } - StringView getExt() const { return Ext; } - const Node *getTA() const { return TA; } - - template void match(Fn F) const { F(Ty, Ext, TA); } - - void printLeft(OutputBuffer &OB) const override { - Ty->print(OB); - OB += " "; - OB += Ext; - if (TA != nullptr) - TA->print(OB); - } -}; - -enum FunctionRefQual : unsigned char { - FrefQualNone, - FrefQualLValue, - FrefQualRValue, -}; - -enum Qualifiers { - QualNone = 0, - QualConst = 0x1, - QualVolatile = 0x2, - QualRestrict = 0x4, -}; - -inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) { - return Q1 = static_cast(Q1 | Q2); -} - -class QualType final : public Node { -protected: - const Qualifiers Quals; - const Node *Child; - - void printQuals(OutputBuffer &OB) const { - if (Quals & QualConst) - OB += " const"; - if (Quals & QualVolatile) - OB += " volatile"; - if (Quals & QualRestrict) - OB += " restrict"; - } - -public: - QualType(const Node *Child_, Qualifiers Quals_) - : Node(KQualType, Child_->RHSComponentCache, - Child_->ArrayCache, Child_->FunctionCache), - Quals(Quals_), Child(Child_) {} - - Qualifiers getQuals() const { return Quals; } - const Node *getChild() const { return Child; } - - template void match(Fn F) const { F(Child, Quals); } - - bool hasRHSComponentSlow(OutputBuffer &OB) const override { - return Child->hasRHSComponent(OB); - } - bool hasArraySlow(OutputBuffer &OB) const override { - return Child->hasArray(OB); - } - bool hasFunctionSlow(OutputBuffer &OB) const override { - return Child->hasFunction(OB); - } - - void printLeft(OutputBuffer &OB) const override { - Child->printLeft(OB); - printQuals(OB); - } - - void printRight(OutputBuffer &OB) const override { Child->printRight(OB); } -}; - -class ConversionOperatorType final : public Node { - const Node *Ty; - -public: - ConversionOperatorType(const Node *Ty_) - : Node(KConversionOperatorType), Ty(Ty_) {} - - template void match(Fn F) const { F(Ty); } - - void printLeft(OutputBuffer &OB) const override { - OB += "operator "; - Ty->print(OB); - } -}; - -class PostfixQualifiedType final : public Node { - const Node *Ty; - const StringView Postfix; - -public: - PostfixQualifiedType(const Node *Ty_, StringView Postfix_) - : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} - - template void match(Fn F) const { F(Ty, Postfix); } - - void printLeft(OutputBuffer &OB) const override { - Ty->printLeft(OB); - OB += Postfix; - } -}; - -class NameType final : public Node { - const StringView Name; - -public: - NameType(StringView Name_) : Node(KNameType), Name(Name_) {} - - template void match(Fn F) const { F(Name); } - - StringView getName() const { return Name; } - StringView getBaseName() const override { return Name; } - - void printLeft(OutputBuffer &OB) const override { OB += Name; } -}; - -class BitIntType final : public Node { - const Node *Size; - bool Signed; - -public: - BitIntType(const Node *Size_, bool Signed_) - : Node(KBitIntType), Size(Size_), Signed(Signed_) {} - - template void match(Fn F) const { F(Size, Signed); } - - void printLeft(OutputBuffer &OB) const override { - if (!Signed) - OB += "unsigned "; - OB += "_BitInt"; - OB.printOpen(); - Size->printAsOperand(OB); - OB.printClose(); - } -}; - -class ElaboratedTypeSpefType : public Node { - StringView Kind; - Node *Child; -public: - ElaboratedTypeSpefType(StringView Kind_, Node *Child_) - : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {} - - template void match(Fn F) const { F(Kind, Child); } - - void printLeft(OutputBuffer &OB) const override { - OB += Kind; - OB += ' '; - Child->print(OB); - } -}; - -struct AbiTagAttr : Node { - Node *Base; - StringView Tag; - - AbiTagAttr(Node* Base_, StringView Tag_) - : Node(KAbiTagAttr, Base_->RHSComponentCache, - Base_->ArrayCache, Base_->FunctionCache), - Base(Base_), Tag(Tag_) {} - - template void match(Fn F) const { F(Base, Tag); } - - void printLeft(OutputBuffer &OB) const override { - Base->printLeft(OB); - OB += "[abi:"; - OB += Tag; - OB += "]"; - } -}; - -class EnableIfAttr : public Node { - NodeArray Conditions; -public: - EnableIfAttr(NodeArray Conditions_) - : Node(KEnableIfAttr), Conditions(Conditions_) {} - - template void match(Fn F) const { F(Conditions); } - - void printLeft(OutputBuffer &OB) const override { - OB += " [enable_if:"; - Conditions.printWithComma(OB); - OB += ']'; - } -}; - -class ObjCProtoName : public Node { - const Node *Ty; - StringView Protocol; - - friend class PointerType; - -public: - ObjCProtoName(const Node *Ty_, StringView Protocol_) - : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {} - - template void match(Fn F) const { F(Ty, Protocol); } - - bool isObjCObject() const { - return Ty->getKind() == KNameType && - static_cast(Ty)->getName() == "objc_object"; - } - - void printLeft(OutputBuffer &OB) const override { - Ty->print(OB); - OB += "<"; - OB += Protocol; - OB += ">"; - } -}; - -class PointerType final : public Node { - const Node *Pointee; - -public: - PointerType(const Node *Pointee_) - : Node(KPointerType, Pointee_->RHSComponentCache), - Pointee(Pointee_) {} - - const Node *getPointee() const { return Pointee; } - - template void match(Fn F) const { F(Pointee); } - - bool hasRHSComponentSlow(OutputBuffer &OB) const override { - return Pointee->hasRHSComponent(OB); - } - - void printLeft(OutputBuffer &OB) const override { - // We rewrite objc_object* into id. - if (Pointee->getKind() != KObjCProtoName || - !static_cast(Pointee)->isObjCObject()) { - Pointee->printLeft(OB); - if (Pointee->hasArray(OB)) - OB += " "; - if (Pointee->hasArray(OB) || Pointee->hasFunction(OB)) - OB += "("; - OB += "*"; - } else { - const auto *objcProto = static_cast(Pointee); - OB += "id<"; - OB += objcProto->Protocol; - OB += ">"; - } - } - - void printRight(OutputBuffer &OB) const override { - if (Pointee->getKind() != KObjCProtoName || - !static_cast(Pointee)->isObjCObject()) { - if (Pointee->hasArray(OB) || Pointee->hasFunction(OB)) - OB += ")"; - Pointee->printRight(OB); - } - } -}; - -enum class ReferenceKind { - LValue, - RValue, -}; - -// Represents either a LValue or an RValue reference type. -class ReferenceType : public Node { - const Node *Pointee; - ReferenceKind RK; - - mutable bool Printing = false; - - // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The - // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any - // other combination collapses to a lvalue ref. - // - // A combination of a TemplateForwardReference and a back-ref Substitution - // from an ill-formed string may have created a cycle; use cycle detection to - // avoid looping forever. - std::pair collapse(OutputBuffer &OB) const { - auto SoFar = std::make_pair(RK, Pointee); - // Track the chain of nodes for the Floyd's 'tortoise and hare' - // cycle-detection algorithm, since getSyntaxNode(S) is impure - PODSmallVector Prev; - for (;;) { - const Node *SN = SoFar.second->getSyntaxNode(OB); - if (SN->getKind() != KReferenceType) - break; - auto *RT = static_cast(SN); - SoFar.second = RT->Pointee; - SoFar.first = std::min(SoFar.first, RT->RK); - - // The middle of Prev is the 'slow' pointer moving at half speed - Prev.push_back(SoFar.second); - if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) { - // Cycle detected - SoFar.second = nullptr; - break; - } - } - return SoFar; - } - -public: - ReferenceType(const Node *Pointee_, ReferenceKind RK_) - : Node(KReferenceType, Pointee_->RHSComponentCache), - Pointee(Pointee_), RK(RK_) {} - - template void match(Fn F) const { F(Pointee, RK); } - - bool hasRHSComponentSlow(OutputBuffer &OB) const override { - return Pointee->hasRHSComponent(OB); - } - - void printLeft(OutputBuffer &OB) const override { - if (Printing) - return; - ScopedOverride SavePrinting(Printing, true); - std::pair Collapsed = collapse(OB); - if (!Collapsed.second) - return; - Collapsed.second->printLeft(OB); - if (Collapsed.second->hasArray(OB)) - OB += " "; - if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB)) - OB += "("; - - OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&"); - } - void printRight(OutputBuffer &OB) const override { - if (Printing) - return; - ScopedOverride SavePrinting(Printing, true); - std::pair Collapsed = collapse(OB); - if (!Collapsed.second) - return; - if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB)) - OB += ")"; - Collapsed.second->printRight(OB); - } -}; - -class PointerToMemberType final : public Node { - const Node *ClassType; - const Node *MemberType; - -public: - PointerToMemberType(const Node *ClassType_, const Node *MemberType_) - : Node(KPointerToMemberType, MemberType_->RHSComponentCache), - ClassType(ClassType_), MemberType(MemberType_) {} - - template void match(Fn F) const { F(ClassType, MemberType); } - - bool hasRHSComponentSlow(OutputBuffer &OB) const override { - return MemberType->hasRHSComponent(OB); - } - - void printLeft(OutputBuffer &OB) const override { - MemberType->printLeft(OB); - if (MemberType->hasArray(OB) || MemberType->hasFunction(OB)) - OB += "("; - else - OB += " "; - ClassType->print(OB); - OB += "::*"; - } - - void printRight(OutputBuffer &OB) const override { - if (MemberType->hasArray(OB) || MemberType->hasFunction(OB)) - OB += ")"; - MemberType->printRight(OB); - } -}; - -class ArrayType final : public Node { - const Node *Base; - Node *Dimension; - -public: - ArrayType(const Node *Base_, Node *Dimension_) - : Node(KArrayType, - /*RHSComponentCache=*/Cache::Yes, - /*ArrayCache=*/Cache::Yes), - Base(Base_), Dimension(Dimension_) {} - - template void match(Fn F) const { F(Base, Dimension); } - - bool hasRHSComponentSlow(OutputBuffer &) const override { return true; } - bool hasArraySlow(OutputBuffer &) const override { return true; } - - void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); } - - void printRight(OutputBuffer &OB) const override { - if (OB.back() != ']') - OB += " "; - OB += "["; - if (Dimension) - Dimension->print(OB); - OB += "]"; - Base->printRight(OB); - } -}; - -class FunctionType final : public Node { - const Node *Ret; - NodeArray Params; - Qualifiers CVQuals; - FunctionRefQual RefQual; - const Node *ExceptionSpec; - -public: - FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_, - FunctionRefQual RefQual_, const Node *ExceptionSpec_) - : Node(KFunctionType, - /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No, - /*FunctionCache=*/Cache::Yes), - Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_), - ExceptionSpec(ExceptionSpec_) {} - - template void match(Fn F) const { - F(Ret, Params, CVQuals, RefQual, ExceptionSpec); - } - - bool hasRHSComponentSlow(OutputBuffer &) const override { return true; } - bool hasFunctionSlow(OutputBuffer &) const override { return true; } - - // Handle C++'s ... quirky decl grammar by using the left & right - // distinction. Consider: - // int (*f(float))(char) {} - // f is a function that takes a float and returns a pointer to a function - // that takes a char and returns an int. If we're trying to print f, start - // by printing out the return types's left, then print our parameters, then - // finally print right of the return type. - void printLeft(OutputBuffer &OB) const override { - Ret->printLeft(OB); - OB += " "; - } - - void printRight(OutputBuffer &OB) const override { - OB.printOpen(); - Params.printWithComma(OB); - OB.printClose(); - Ret->printRight(OB); - - if (CVQuals & QualConst) - OB += " const"; - if (CVQuals & QualVolatile) - OB += " volatile"; - if (CVQuals & QualRestrict) - OB += " restrict"; - - if (RefQual == FrefQualLValue) - OB += " &"; - else if (RefQual == FrefQualRValue) - OB += " &&"; - - if (ExceptionSpec != nullptr) { - OB += ' '; - ExceptionSpec->print(OB); - } - } -}; - -class NoexceptSpec : public Node { - const Node *E; -public: - NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {} - - template void match(Fn F) const { F(E); } - - void printLeft(OutputBuffer &OB) const override { - OB += "noexcept"; - OB.printOpen(); - E->printAsOperand(OB); - OB.printClose(); - } -}; - -class DynamicExceptionSpec : public Node { - NodeArray Types; -public: - DynamicExceptionSpec(NodeArray Types_) - : Node(KDynamicExceptionSpec), Types(Types_) {} - - template void match(Fn F) const { F(Types); } - - void printLeft(OutputBuffer &OB) const override { - OB += "throw"; - OB.printOpen(); - Types.printWithComma(OB); - OB.printClose(); - } -}; - -class FunctionEncoding final : public Node { - const Node *Ret; - const Node *Name; - NodeArray Params; - const Node *Attrs; - Qualifiers CVQuals; - FunctionRefQual RefQual; - -public: - FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_, - const Node *Attrs_, Qualifiers CVQuals_, - FunctionRefQual RefQual_) - : Node(KFunctionEncoding, - /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No, - /*FunctionCache=*/Cache::Yes), - Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_), - CVQuals(CVQuals_), RefQual(RefQual_) {} - - template void match(Fn F) const { - F(Ret, Name, Params, Attrs, CVQuals, RefQual); - } - - Qualifiers getCVQuals() const { return CVQuals; } - FunctionRefQual getRefQual() const { return RefQual; } - NodeArray getParams() const { return Params; } - const Node *getReturnType() const { return Ret; } - - bool hasRHSComponentSlow(OutputBuffer &) const override { return true; } - bool hasFunctionSlow(OutputBuffer &) const override { return true; } - - const Node *getName() const { return Name; } - - void printLeft(OutputBuffer &OB) const override { - if (Ret) { - Ret->printLeft(OB); - if (!Ret->hasRHSComponent(OB)) - OB += " "; - } - Name->print(OB); - } - - void printRight(OutputBuffer &OB) const override { - OB.printOpen(); - Params.printWithComma(OB); - OB.printClose(); - if (Ret) - Ret->printRight(OB); - - if (CVQuals & QualConst) - OB += " const"; - if (CVQuals & QualVolatile) - OB += " volatile"; - if (CVQuals & QualRestrict) - OB += " restrict"; - - if (RefQual == FrefQualLValue) - OB += " &"; - else if (RefQual == FrefQualRValue) - OB += " &&"; - - if (Attrs != nullptr) - Attrs->print(OB); - } -}; - -class LiteralOperator : public Node { - const Node *OpName; - -public: - LiteralOperator(const Node *OpName_) - : Node(KLiteralOperator), OpName(OpName_) {} - - template void match(Fn F) const { F(OpName); } - - void printLeft(OutputBuffer &OB) const override { - OB += "operator\"\" "; - OpName->print(OB); - } -}; - -class SpecialName final : public Node { - const StringView Special; - const Node *Child; - -public: - SpecialName(StringView Special_, const Node *Child_) - : Node(KSpecialName), Special(Special_), Child(Child_) {} - - template void match(Fn F) const { F(Special, Child); } - - void printLeft(OutputBuffer &OB) const override { - OB += Special; - Child->print(OB); - } -}; - -class CtorVtableSpecialName final : public Node { - const Node *FirstType; - const Node *SecondType; - -public: - CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_) - : Node(KCtorVtableSpecialName), - FirstType(FirstType_), SecondType(SecondType_) {} - - template void match(Fn F) const { F(FirstType, SecondType); } - - void printLeft(OutputBuffer &OB) const override { - OB += "construction vtable for "; - FirstType->print(OB); - OB += "-in-"; - SecondType->print(OB); - } -}; - -struct NestedName : Node { - Node *Qual; - Node *Name; - - NestedName(Node *Qual_, Node *Name_) - : Node(KNestedName), Qual(Qual_), Name(Name_) {} - - template void match(Fn F) const { F(Qual, Name); } - - StringView getBaseName() const override { return Name->getBaseName(); } - - void printLeft(OutputBuffer &OB) const override { - Qual->print(OB); - OB += "::"; - Name->print(OB); - } -}; - -struct ModuleName : Node { - ModuleName *Parent; - Node *Name; - bool IsPartition; - - ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false) - : Node(KModuleName), Parent(Parent_), Name(Name_), - IsPartition(IsPartition_) {} - - template void match(Fn F) const { - F(Parent, Name, IsPartition); - } - - void printLeft(OutputBuffer &OB) const override { - if (Parent) - Parent->print(OB); - if (Parent || IsPartition) - OB += IsPartition ? ':' : '.'; - Name->print(OB); - } -}; - -struct ModuleEntity : Node { - ModuleName *Module; - Node *Name; - - ModuleEntity(ModuleName *Module_, Node *Name_) - : Node(KModuleEntity), Module(Module_), Name(Name_) {} - - template void match(Fn F) const { F(Module, Name); } - - StringView getBaseName() const override { return Name->getBaseName(); } - - void printLeft(OutputBuffer &OB) const override { - Name->print(OB); - OB += '@'; - Module->print(OB); - } -}; - -struct LocalName : Node { - Node *Encoding; - Node *Entity; - - LocalName(Node *Encoding_, Node *Entity_) - : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {} - - template void match(Fn F) const { F(Encoding, Entity); } - - void printLeft(OutputBuffer &OB) const override { - Encoding->print(OB); - OB += "::"; - Entity->print(OB); - } -}; - -class QualifiedName final : public Node { - // qualifier::name - const Node *Qualifier; - const Node *Name; - -public: - QualifiedName(const Node *Qualifier_, const Node *Name_) - : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {} - - template void match(Fn F) const { F(Qualifier, Name); } - - StringView getBaseName() const override { return Name->getBaseName(); } - - void printLeft(OutputBuffer &OB) const override { - Qualifier->print(OB); - OB += "::"; - Name->print(OB); - } -}; - -class VectorType final : public Node { - const Node *BaseType; - const Node *Dimension; - -public: - VectorType(const Node *BaseType_, const Node *Dimension_) - : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {} - - const Node *getBaseType() const { return BaseType; } - const Node *getDimension() const { return Dimension; } - - template void match(Fn F) const { F(BaseType, Dimension); } - - void printLeft(OutputBuffer &OB) const override { - BaseType->print(OB); - OB += " vector["; - if (Dimension) - Dimension->print(OB); - OB += "]"; - } -}; - -class PixelVectorType final : public Node { - const Node *Dimension; - -public: - PixelVectorType(const Node *Dimension_) - : Node(KPixelVectorType), Dimension(Dimension_) {} - - template void match(Fn F) const { F(Dimension); } - - void printLeft(OutputBuffer &OB) const override { - // FIXME: This should demangle as "vector pixel". - OB += "pixel vector["; - Dimension->print(OB); - OB += "]"; - } -}; - -class BinaryFPType final : public Node { - const Node *Dimension; - -public: - BinaryFPType(const Node *Dimension_) - : Node(KBinaryFPType), Dimension(Dimension_) {} - - template void match(Fn F) const { F(Dimension); } - - void printLeft(OutputBuffer &OB) const override { - OB += "_Float"; - Dimension->print(OB); - } -}; - -enum class TemplateParamKind { Type, NonType, Template }; - -/// An invented name for a template parameter for which we don't have a -/// corresponding template argument. -/// -/// This node is created when parsing the for a lambda with -/// explicit template arguments, which might be referenced in the parameter -/// types appearing later in the . -class SyntheticTemplateParamName final : public Node { - TemplateParamKind Kind; - unsigned Index; - -public: - SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_) - : Node(KSyntheticTemplateParamName), Kind(Kind_), Index(Index_) {} - - template void match(Fn F) const { F(Kind, Index); } - - void printLeft(OutputBuffer &OB) const override { - switch (Kind) { - case TemplateParamKind::Type: - OB += "$T"; - break; - case TemplateParamKind::NonType: - OB += "$N"; - break; - case TemplateParamKind::Template: - OB += "$TT"; - break; - } - if (Index > 0) - OB << Index - 1; - } -}; - -/// A template type parameter declaration, 'typename T'. -class TypeTemplateParamDecl final : public Node { - Node *Name; - -public: - TypeTemplateParamDecl(Node *Name_) - : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {} - - template void match(Fn F) const { F(Name); } - - void printLeft(OutputBuffer &OB) const override { OB += "typename "; } - - void printRight(OutputBuffer &OB) const override { Name->print(OB); } -}; - -/// A non-type template parameter declaration, 'int N'. -class NonTypeTemplateParamDecl final : public Node { - Node *Name; - Node *Type; - -public: - NonTypeTemplateParamDecl(Node *Name_, Node *Type_) - : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {} - - template void match(Fn F) const { F(Name, Type); } - - void printLeft(OutputBuffer &OB) const override { - Type->printLeft(OB); - if (!Type->hasRHSComponent(OB)) - OB += " "; - } - - void printRight(OutputBuffer &OB) const override { - Name->print(OB); - Type->printRight(OB); - } -}; - -/// A template template parameter declaration, -/// 'template typename N'. -class TemplateTemplateParamDecl final : public Node { - Node *Name; - NodeArray Params; - -public: - TemplateTemplateParamDecl(Node *Name_, NodeArray Params_) - : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_), - Params(Params_) {} - - template void match(Fn F) const { F(Name, Params); } - - void printLeft(OutputBuffer &OB) const override { - ScopedOverride LT(OB.GtIsGt, 0); - OB += "template<"; - Params.printWithComma(OB); - OB += "> typename "; - } - - void printRight(OutputBuffer &OB) const override { Name->print(OB); } -}; - -/// A template parameter pack declaration, 'typename ...T'. -class TemplateParamPackDecl final : public Node { - Node *Param; - -public: - TemplateParamPackDecl(Node *Param_) - : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {} - - template void match(Fn F) const { F(Param); } - - void printLeft(OutputBuffer &OB) const override { - Param->printLeft(OB); - OB += "..."; - } - - void printRight(OutputBuffer &OB) const override { Param->printRight(OB); } -}; - -/// An unexpanded parameter pack (either in the expression or type context). If -/// this AST is correct, this node will have a ParameterPackExpansion node above -/// it. -/// -/// This node is created when some are found that apply to an -/// , and is stored in the TemplateParams table. In order for this to -/// appear in the final AST, it has to referenced via a (ie, -/// T_). -class ParameterPack final : public Node { - NodeArray Data; - - // Setup OutputBuffer for a pack expansion, unless we're already expanding - // one. - void initializePackExpansion(OutputBuffer &OB) const { - if (OB.CurrentPackMax == std::numeric_limits::max()) { - OB.CurrentPackMax = static_cast(Data.size()); - OB.CurrentPackIndex = 0; - } - } - -public: - ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) { - ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown; - if (std::all_of(Data.begin(), Data.end(), [](Node* P) { - return P->ArrayCache == Cache::No; - })) - ArrayCache = Cache::No; - if (std::all_of(Data.begin(), Data.end(), [](Node* P) { - return P->FunctionCache == Cache::No; - })) - FunctionCache = Cache::No; - if (std::all_of(Data.begin(), Data.end(), [](Node* P) { - return P->RHSComponentCache == Cache::No; - })) - RHSComponentCache = Cache::No; - } - - template void match(Fn F) const { F(Data); } - - bool hasRHSComponentSlow(OutputBuffer &OB) const override { - initializePackExpansion(OB); - size_t Idx = OB.CurrentPackIndex; - return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB); - } - bool hasArraySlow(OutputBuffer &OB) const override { - initializePackExpansion(OB); - size_t Idx = OB.CurrentPackIndex; - return Idx < Data.size() && Data[Idx]->hasArray(OB); - } - bool hasFunctionSlow(OutputBuffer &OB) const override { - initializePackExpansion(OB); - size_t Idx = OB.CurrentPackIndex; - return Idx < Data.size() && Data[Idx]->hasFunction(OB); - } - const Node *getSyntaxNode(OutputBuffer &OB) const override { - initializePackExpansion(OB); - size_t Idx = OB.CurrentPackIndex; - return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this; - } - - void printLeft(OutputBuffer &OB) const override { - initializePackExpansion(OB); - size_t Idx = OB.CurrentPackIndex; - if (Idx < Data.size()) - Data[Idx]->printLeft(OB); - } - void printRight(OutputBuffer &OB) const override { - initializePackExpansion(OB); - size_t Idx = OB.CurrentPackIndex; - if (Idx < Data.size()) - Data[Idx]->printRight(OB); - } -}; - -/// A variadic template argument. This node represents an occurrence of -/// JE in some . It isn't itself unexpanded, unless -/// one of it's Elements is. The parser inserts a ParameterPack into the -/// TemplateParams table if the this pack belongs to apply to an -/// . -class TemplateArgumentPack final : public Node { - NodeArray Elements; -public: - TemplateArgumentPack(NodeArray Elements_) - : Node(KTemplateArgumentPack), Elements(Elements_) {} - - template void match(Fn F) const { F(Elements); } - - NodeArray getElements() const { return Elements; } - - void printLeft(OutputBuffer &OB) const override { - Elements.printWithComma(OB); - } -}; - -/// A pack expansion. Below this node, there are some unexpanded ParameterPacks -/// which each have Child->ParameterPackSize elements. -class ParameterPackExpansion final : public Node { - const Node *Child; - -public: - ParameterPackExpansion(const Node *Child_) - : Node(KParameterPackExpansion), Child(Child_) {} - - template void match(Fn F) const { F(Child); } - - const Node *getChild() const { return Child; } - - void printLeft(OutputBuffer &OB) const override { - constexpr unsigned Max = std::numeric_limits::max(); - ScopedOverride SavePackIdx(OB.CurrentPackIndex, Max); - ScopedOverride SavePackMax(OB.CurrentPackMax, Max); - size_t StreamPos = OB.getCurrentPosition(); - - // Print the first element in the pack. If Child contains a ParameterPack, - // it will set up S.CurrentPackMax and print the first element. - Child->print(OB); - - // No ParameterPack was found in Child. This can occur if we've found a pack - // expansion on a . - if (OB.CurrentPackMax == Max) { - OB += "..."; - return; - } - - // We found a ParameterPack, but it has no elements. Erase whatever we may - // of printed. - if (OB.CurrentPackMax == 0) { - OB.setCurrentPosition(StreamPos); - return; - } - - // Else, iterate through the rest of the elements in the pack. - for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) { - OB += ", "; - OB.CurrentPackIndex = I; - Child->print(OB); - } - } -}; - -class TemplateArgs final : public Node { - NodeArray Params; - -public: - TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {} - - template void match(Fn F) const { F(Params); } - - NodeArray getParams() { return Params; } - - void printLeft(OutputBuffer &OB) const override { - ScopedOverride LT(OB.GtIsGt, 0); - OB += "<"; - Params.printWithComma(OB); - OB += ">"; - } -}; - -/// A forward-reference to a template argument that was not known at the point -/// where the template parameter name was parsed in a mangling. -/// -/// This is created when demangling the name of a specialization of a -/// conversion function template: -/// -/// \code -/// struct A { -/// template operator T*(); -/// }; -/// \endcode -/// -/// When demangling a specialization of the conversion function template, we -/// encounter the name of the template (including the \c T) before we reach -/// the template argument list, so we cannot substitute the parameter name -/// for the corresponding argument while parsing. Instead, we create a -/// \c ForwardTemplateReference node that is resolved after we parse the -/// template arguments. -struct ForwardTemplateReference : Node { - size_t Index; - Node *Ref = nullptr; - - // If we're currently printing this node. It is possible (though invalid) for - // a forward template reference to refer to itself via a substitution. This - // creates a cyclic AST, which will stack overflow printing. To fix this, bail - // out if more than one print* function is active. - mutable bool Printing = false; - - ForwardTemplateReference(size_t Index_) - : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown, - Cache::Unknown), - Index(Index_) {} - - // We don't provide a matcher for these, because the value of the node is - // not determined by its construction parameters, and it generally needs - // special handling. - template void match(Fn F) const = delete; - - bool hasRHSComponentSlow(OutputBuffer &OB) const override { - if (Printing) - return false; - ScopedOverride SavePrinting(Printing, true); - return Ref->hasRHSComponent(OB); - } - bool hasArraySlow(OutputBuffer &OB) const override { - if (Printing) - return false; - ScopedOverride SavePrinting(Printing, true); - return Ref->hasArray(OB); - } - bool hasFunctionSlow(OutputBuffer &OB) const override { - if (Printing) - return false; - ScopedOverride SavePrinting(Printing, true); - return Ref->hasFunction(OB); - } - const Node *getSyntaxNode(OutputBuffer &OB) const override { - if (Printing) - return this; - ScopedOverride SavePrinting(Printing, true); - return Ref->getSyntaxNode(OB); - } - - void printLeft(OutputBuffer &OB) const override { - if (Printing) - return; - ScopedOverride SavePrinting(Printing, true); - Ref->printLeft(OB); - } - void printRight(OutputBuffer &OB) const override { - if (Printing) - return; - ScopedOverride SavePrinting(Printing, true); - Ref->printRight(OB); - } -}; - -struct NameWithTemplateArgs : Node { - // name - Node *Name; - Node *TemplateArgs; - - NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_) - : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {} - - template void match(Fn F) const { F(Name, TemplateArgs); } - - StringView getBaseName() const override { return Name->getBaseName(); } - - void printLeft(OutputBuffer &OB) const override { - Name->print(OB); - TemplateArgs->print(OB); - } -}; - -class GlobalQualifiedName final : public Node { - Node *Child; - -public: - GlobalQualifiedName(Node* Child_) - : Node(KGlobalQualifiedName), Child(Child_) {} - - template void match(Fn F) const { F(Child); } - - StringView getBaseName() const override { return Child->getBaseName(); } - - void printLeft(OutputBuffer &OB) const override { - OB += "::"; - Child->print(OB); - } -}; - -enum class SpecialSubKind { - allocator, - basic_string, - string, - istream, - ostream, - iostream, -}; - -class SpecialSubstitution; -class ExpandedSpecialSubstitution : public Node { -protected: - SpecialSubKind SSK; - - ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_) - : Node(K_), SSK(SSK_) {} -public: - ExpandedSpecialSubstitution(SpecialSubKind SSK_) - : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {} - inline ExpandedSpecialSubstitution(SpecialSubstitution const *); - - template void match(Fn F) const { F(SSK); } - -protected: - bool isInstantiation() const { - return unsigned(SSK) >= unsigned(SpecialSubKind::string); - } - - StringView getBaseName() const override { - switch (SSK) { - case SpecialSubKind::allocator: - return StringView("allocator"); - case SpecialSubKind::basic_string: - return StringView("basic_string"); - case SpecialSubKind::string: - return StringView("basic_string"); - case SpecialSubKind::istream: - return StringView("basic_istream"); - case SpecialSubKind::ostream: - return StringView("basic_ostream"); - case SpecialSubKind::iostream: - return StringView("basic_iostream"); - } - DEMANGLE_UNREACHABLE; - } - -private: - void printLeft(OutputBuffer &OB) const override { - OB << "std::" << getBaseName(); - if (isInstantiation()) { - OB << ""; - if (SSK == SpecialSubKind::string) - OB << ", std::allocator"; - OB << ">"; - } - } -}; - -class SpecialSubstitution final : public ExpandedSpecialSubstitution { -public: - SpecialSubstitution(SpecialSubKind SSK_) - : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {} - - template void match(Fn F) const { F(SSK); } - - StringView getBaseName() const override { - auto SV = ExpandedSpecialSubstitution::getBaseName (); - if (isInstantiation()) { - // The instantiations are typedefs that drop the "basic_" prefix. - assert(SV.startsWith("basic_")); - SV = SV.dropFront(sizeof("basic_") - 1); - } - return SV; - } - - void printLeft(OutputBuffer &OB) const override { - OB << "std::" << getBaseName(); - } -}; - -inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution( - SpecialSubstitution const *SS) - : ExpandedSpecialSubstitution(SS->SSK) {} - -class CtorDtorName final : public Node { - const Node *Basename; - const bool IsDtor; - const int Variant; - -public: - CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_) - : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_), - Variant(Variant_) {} - - template void match(Fn F) const { F(Basename, IsDtor, Variant); } - - void printLeft(OutputBuffer &OB) const override { - if (IsDtor) - OB += "~"; - OB += Basename->getBaseName(); - } -}; - -class DtorName : public Node { - const Node *Base; - -public: - DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {} - - template void match(Fn F) const { F(Base); } - - void printLeft(OutputBuffer &OB) const override { - OB += "~"; - Base->printLeft(OB); - } -}; - -class UnnamedTypeName : public Node { - const StringView Count; - -public: - UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {} - - template void match(Fn F) const { F(Count); } - - void printLeft(OutputBuffer &OB) const override { - OB += "'unnamed"; - OB += Count; - OB += "\'"; - } -}; - -class ClosureTypeName : public Node { - NodeArray TemplateParams; - NodeArray Params; - StringView Count; - -public: - ClosureTypeName(NodeArray TemplateParams_, NodeArray Params_, - StringView Count_) - : Node(KClosureTypeName), TemplateParams(TemplateParams_), - Params(Params_), Count(Count_) {} - - template void match(Fn F) const { - F(TemplateParams, Params, Count); - } - - void printDeclarator(OutputBuffer &OB) const { - if (!TemplateParams.empty()) { - ScopedOverride LT(OB.GtIsGt, 0); - OB += "<"; - TemplateParams.printWithComma(OB); - OB += ">"; - } - OB.printOpen(); - Params.printWithComma(OB); - OB.printClose(); - } - - void printLeft(OutputBuffer &OB) const override { - OB += "\'lambda"; - OB += Count; - OB += "\'"; - printDeclarator(OB); - } -}; - -class StructuredBindingName : public Node { - NodeArray Bindings; -public: - StructuredBindingName(NodeArray Bindings_) - : Node(KStructuredBindingName), Bindings(Bindings_) {} - - template void match(Fn F) const { F(Bindings); } - - void printLeft(OutputBuffer &OB) const override { - OB.printOpen('['); - Bindings.printWithComma(OB); - OB.printClose(']'); - } -}; - -// -- Expression Nodes -- - -class BinaryExpr : public Node { - const Node *LHS; - const StringView InfixOperator; - const Node *RHS; - -public: - BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_, - Prec Prec_) - : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_), - RHS(RHS_) {} - - template void match(Fn F) const { - F(LHS, InfixOperator, RHS, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - bool ParenAll = OB.isGtInsideTemplateArgs() && - (InfixOperator == ">" || InfixOperator == ">>"); - if (ParenAll) - OB.printOpen(); - // Assignment is right associative, with special LHS precedence. - bool IsAssign = getPrecedence() == Prec::Assign; - LHS->printAsOperand(OB, IsAssign ? Prec::OrIf : getPrecedence(), !IsAssign); - // No space before comma operator - if (!(InfixOperator == ",")) - OB += " "; - OB += InfixOperator; - OB += " "; - RHS->printAsOperand(OB, getPrecedence(), IsAssign); - if (ParenAll) - OB.printClose(); - } -}; - -class ArraySubscriptExpr : public Node { - const Node *Op1; - const Node *Op2; - -public: - ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_) - : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {} - - template void match(Fn F) const { - F(Op1, Op2, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - Op1->printAsOperand(OB, getPrecedence()); - OB.printOpen('['); - Op2->printAsOperand(OB); - OB.printClose(']'); - } -}; - -class PostfixExpr : public Node { - const Node *Child; - const StringView Operator; - -public: - PostfixExpr(const Node *Child_, StringView Operator_, Prec Prec_) - : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {} - - template void match(Fn F) const { - F(Child, Operator, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - Child->printAsOperand(OB, getPrecedence(), true); - OB += Operator; - } -}; - -class ConditionalExpr : public Node { - const Node *Cond; - const Node *Then; - const Node *Else; - -public: - ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_, - Prec Prec_) - : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {} - - template void match(Fn F) const { - F(Cond, Then, Else, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - Cond->printAsOperand(OB, getPrecedence()); - OB += " ? "; - Then->printAsOperand(OB); - OB += " : "; - Else->printAsOperand(OB, Prec::Assign, true); - } -}; - -class MemberExpr : public Node { - const Node *LHS; - const StringView Kind; - const Node *RHS; - -public: - MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_, Prec Prec_) - : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {} - - template void match(Fn F) const { - F(LHS, Kind, RHS, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - LHS->printAsOperand(OB, getPrecedence(), true); - OB += Kind; - RHS->printAsOperand(OB, getPrecedence(), false); - } -}; - -class SubobjectExpr : public Node { - const Node *Type; - const Node *SubExpr; - StringView Offset; - NodeArray UnionSelectors; - bool OnePastTheEnd; - -public: - SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_, - NodeArray UnionSelectors_, bool OnePastTheEnd_) - : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_), - UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {} - - template void match(Fn F) const { - F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd); - } - - void printLeft(OutputBuffer &OB) const override { - SubExpr->print(OB); - OB += ".<"; - Type->print(OB); - OB += " at offset "; - if (Offset.empty()) { - OB += "0"; - } else if (Offset[0] == 'n') { - OB += "-"; - OB += Offset.dropFront(); - } else { - OB += Offset; - } - OB += ">"; - } -}; - -class EnclosingExpr : public Node { - const StringView Prefix; - const Node *Infix; - const StringView Postfix; - -public: - EnclosingExpr(StringView Prefix_, const Node *Infix_, - Prec Prec_ = Prec::Primary) - : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {} - - template void match(Fn F) const { - F(Prefix, Infix, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - OB += Prefix; - OB.printOpen(); - Infix->print(OB); - OB.printClose(); - OB += Postfix; - } -}; - -class CastExpr : public Node { - // cast_kind(from) - const StringView CastKind; - const Node *To; - const Node *From; - -public: - CastExpr(StringView CastKind_, const Node *To_, const Node *From_, Prec Prec_) - : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {} - - template void match(Fn F) const { - F(CastKind, To, From, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - OB += CastKind; - { - ScopedOverride LT(OB.GtIsGt, 0); - OB += "<"; - To->printLeft(OB); - OB += ">"; - } - OB.printOpen(); - From->printAsOperand(OB); - OB.printClose(); - } -}; - -class SizeofParamPackExpr : public Node { - const Node *Pack; - -public: - SizeofParamPackExpr(const Node *Pack_) - : Node(KSizeofParamPackExpr), Pack(Pack_) {} - - template void match(Fn F) const { F(Pack); } - - void printLeft(OutputBuffer &OB) const override { - OB += "sizeof..."; - OB.printOpen(); - ParameterPackExpansion PPE(Pack); - PPE.printLeft(OB); - OB.printClose(); - } -}; - -class CallExpr : public Node { - const Node *Callee; - NodeArray Args; - -public: - CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_) - : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {} - - template void match(Fn F) const { - F(Callee, Args, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - Callee->print(OB); - OB.printOpen(); - Args.printWithComma(OB); - OB.printClose(); - } -}; - -class NewExpr : public Node { - // new (expr_list) type(init_list) - NodeArray ExprList; - Node *Type; - NodeArray InitList; - bool IsGlobal; // ::operator new ? - bool IsArray; // new[] ? -public: - NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_, - bool IsArray_, Prec Prec_) - : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_), - InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {} - - template void match(Fn F) const { - F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - if (IsGlobal) - OB += "::"; - OB += "new"; - if (IsArray) - OB += "[]"; - if (!ExprList.empty()) { - OB.printOpen(); - ExprList.printWithComma(OB); - OB.printClose(); - } - OB += " "; - Type->print(OB); - if (!InitList.empty()) { - OB.printOpen(); - InitList.printWithComma(OB); - OB.printClose(); - } - } -}; - -class DeleteExpr : public Node { - Node *Op; - bool IsGlobal; - bool IsArray; - -public: - DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_) - : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_), - IsArray(IsArray_) {} - - template void match(Fn F) const { - F(Op, IsGlobal, IsArray, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - if (IsGlobal) - OB += "::"; - OB += "delete"; - if (IsArray) - OB += "[]"; - OB += ' '; - Op->print(OB); - } -}; - -class PrefixExpr : public Node { - StringView Prefix; - Node *Child; - -public: - PrefixExpr(StringView Prefix_, Node *Child_, Prec Prec_) - : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {} - - template void match(Fn F) const { - F(Prefix, Child, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - OB += Prefix; - Child->printAsOperand(OB, getPrecedence()); - } -}; - -class FunctionParam : public Node { - StringView Number; - -public: - FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {} - - template void match(Fn F) const { F(Number); } - - void printLeft(OutputBuffer &OB) const override { - OB += "fp"; - OB += Number; - } -}; - -class ConversionExpr : public Node { - const Node *Type; - NodeArray Expressions; - -public: - ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_) - : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {} - - template void match(Fn F) const { - F(Type, Expressions, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - OB.printOpen(); - Type->print(OB); - OB.printClose(); - OB.printOpen(); - Expressions.printWithComma(OB); - OB.printClose(); - } -}; - -class PointerToMemberConversionExpr : public Node { - const Node *Type; - const Node *SubExpr; - StringView Offset; - -public: - PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_, - StringView Offset_, Prec Prec_) - : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_), - SubExpr(SubExpr_), Offset(Offset_) {} - - template void match(Fn F) const { - F(Type, SubExpr, Offset, getPrecedence()); - } - - void printLeft(OutputBuffer &OB) const override { - OB.printOpen(); - Type->print(OB); - OB.printClose(); - OB.printOpen(); - SubExpr->print(OB); - OB.printClose(); - } -}; - -class InitListExpr : public Node { - const Node *Ty; - NodeArray Inits; -public: - InitListExpr(const Node *Ty_, NodeArray Inits_) - : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {} - - template void match(Fn F) const { F(Ty, Inits); } - - void printLeft(OutputBuffer &OB) const override { - if (Ty) - Ty->print(OB); - OB += '{'; - Inits.printWithComma(OB); - OB += '}'; - } -}; - -class BracedExpr : public Node { - const Node *Elem; - const Node *Init; - bool IsArray; -public: - BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_) - : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {} - - template void match(Fn F) const { F(Elem, Init, IsArray); } - - void printLeft(OutputBuffer &OB) const override { - if (IsArray) { - OB += '['; - Elem->print(OB); - OB += ']'; - } else { - OB += '.'; - Elem->print(OB); - } - if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) - OB += " = "; - Init->print(OB); - } -}; - -class BracedRangeExpr : public Node { - const Node *First; - const Node *Last; - const Node *Init; -public: - BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_) - : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {} - - template void match(Fn F) const { F(First, Last, Init); } - - void printLeft(OutputBuffer &OB) const override { - OB += '['; - First->print(OB); - OB += " ... "; - Last->print(OB); - OB += ']'; - if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) - OB += " = "; - Init->print(OB); - } -}; - -class FoldExpr : public Node { - const Node *Pack, *Init; - StringView OperatorName; - bool IsLeftFold; - -public: - FoldExpr(bool IsLeftFold_, StringView OperatorName_, const Node *Pack_, - const Node *Init_) - : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_), - IsLeftFold(IsLeftFold_) {} - - template void match(Fn F) const { - F(IsLeftFold, OperatorName, Pack, Init); - } - - void printLeft(OutputBuffer &OB) const override { - auto PrintPack = [&] { - OB.printOpen(); - ParameterPackExpansion(Pack).print(OB); - OB.printClose(); - }; - - OB.printOpen(); - // Either '[init op ]... op pack' or 'pack op ...[ op init]' - // Refactored to '[(init|pack) op ]...[ op (pack|init)]' - // Fold expr operands are cast-expressions - if (!IsLeftFold || Init != nullptr) { - // '(init|pack) op ' - if (IsLeftFold) - Init->printAsOperand(OB, Prec::Cast, true); - else - PrintPack(); - OB << " " << OperatorName << " "; - } - OB << "..."; - if (IsLeftFold || Init != nullptr) { - // ' op (init|pack)' - OB << " " << OperatorName << " "; - if (IsLeftFold) - PrintPack(); - else - Init->printAsOperand(OB, Prec::Cast, true); - } - OB.printClose(); - } -}; - -class ThrowExpr : public Node { - const Node *Op; - -public: - ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {} - - template void match(Fn F) const { F(Op); } - - void printLeft(OutputBuffer &OB) const override { - OB += "throw "; - Op->print(OB); - } -}; - -class BoolExpr : public Node { - bool Value; - -public: - BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {} - - template void match(Fn F) const { F(Value); } - - void printLeft(OutputBuffer &OB) const override { - OB += Value ? StringView("true") : StringView("false"); - } -}; - -class StringLiteral : public Node { - const Node *Type; - -public: - StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {} - - template void match(Fn F) const { F(Type); } - - void printLeft(OutputBuffer &OB) const override { - OB += "\"<"; - Type->print(OB); - OB += ">\""; - } -}; - -class LambdaExpr : public Node { - const Node *Type; - -public: - LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {} - - template void match(Fn F) const { F(Type); } - - void printLeft(OutputBuffer &OB) const override { - OB += "[]"; - if (Type->getKind() == KClosureTypeName) - static_cast(Type)->printDeclarator(OB); - OB += "{...}"; - } -}; - -class EnumLiteral : public Node { - // ty(integer) - const Node *Ty; - StringView Integer; - -public: - EnumLiteral(const Node *Ty_, StringView Integer_) - : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {} - - template void match(Fn F) const { F(Ty, Integer); } - - void printLeft(OutputBuffer &OB) const override { - OB.printOpen(); - Ty->print(OB); - OB.printClose(); - - if (Integer[0] == 'n') - OB << "-" << Integer.dropFront(1); - else - OB << Integer; - } -}; - -class IntegerLiteral : public Node { - StringView Type; - StringView Value; - -public: - IntegerLiteral(StringView Type_, StringView Value_) - : Node(KIntegerLiteral), Type(Type_), Value(Value_) {} - - template void match(Fn F) const { F(Type, Value); } - - void printLeft(OutputBuffer &OB) const override { - if (Type.size() > 3) { - OB.printOpen(); - OB += Type; - OB.printClose(); - } - - if (Value[0] == 'n') { - OB += '-'; - OB += Value.dropFront(1); - } else - OB += Value; - - if (Type.size() <= 3) - OB += Type; - } -}; - -template struct FloatData; - -namespace float_literal_impl { -constexpr Node::Kind getFloatLiteralKind(float *) { - return Node::KFloatLiteral; -} -constexpr Node::Kind getFloatLiteralKind(double *) { - return Node::KDoubleLiteral; -} -constexpr Node::Kind getFloatLiteralKind(long double *) { - return Node::KLongDoubleLiteral; -} -} - -template class FloatLiteralImpl : public Node { - const StringView Contents; - - static constexpr Kind KindForClass = - float_literal_impl::getFloatLiteralKind((Float *)nullptr); - -public: - FloatLiteralImpl(StringView Contents_) - : Node(KindForClass), Contents(Contents_) {} - - template void match(Fn F) const { F(Contents); } - - void printLeft(OutputBuffer &OB) const override { - const char *first = Contents.begin(); - const char *last = Contents.end() + 1; - - const size_t N = FloatData::mangled_size; - if (static_cast(last - first) > N) { - last = first + N; - union { - Float value; - char buf[sizeof(Float)]; - }; - const char *t = first; - char *e = buf; - for (; t != last; ++t, ++e) { - unsigned d1 = isdigit(*t) ? static_cast(*t - '0') - : static_cast(*t - 'a' + 10); - ++t; - unsigned d0 = isdigit(*t) ? static_cast(*t - '0') - : static_cast(*t - 'a' + 10); - *e = static_cast((d1 << 4) + d0); - } -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - std::reverse(buf, e); -#endif - char num[FloatData::max_demangled_size] = {0}; - int n = snprintf(num, sizeof(num), FloatData::spec, value); - OB += StringView(num, num + n); - } - } -}; - -using FloatLiteral = FloatLiteralImpl; -using DoubleLiteral = FloatLiteralImpl; -using LongDoubleLiteral = FloatLiteralImpl; - -/// Visit the node. Calls \c F(P), where \c P is the node cast to the -/// appropriate derived class. -template -void Node::visit(Fn F) const { - switch (K) { -#define NODE(X) \ - case K##X: \ - return F(static_cast(this)); -#include "ItaniumNodes.def" - } - assert(0 && "unknown mangling node kind"); -} - -/// Determine the kind of a node from its type. -template struct NodeKind; -#define NODE(X) \ - template <> struct NodeKind { \ - static constexpr Node::Kind Kind = Node::K##X; \ - static constexpr const char *name() { return #X; } \ - }; -#include "ItaniumNodes.def" - -template struct AbstractManglingParser { - const char *First; - const char *Last; - - // Name stack, this is used by the parser to hold temporary names that were - // parsed. The parser collapses multiple names into new nodes to construct - // the AST. Once the parser is finished, names.size() == 1. - PODSmallVector Names; - - // Substitution table. Itanium supports name substitutions as a means of - // compression. The string "S42_" refers to the 44nd entry (base-36) in this - // table. - PODSmallVector Subs; - - using TemplateParamList = PODSmallVector; - - class ScopedTemplateParamList { - AbstractManglingParser *Parser; - size_t OldNumTemplateParamLists; - TemplateParamList Params; - - public: - ScopedTemplateParamList(AbstractManglingParser *TheParser) - : Parser(TheParser), - OldNumTemplateParamLists(TheParser->TemplateParams.size()) { - Parser->TemplateParams.push_back(&Params); - } - ~ScopedTemplateParamList() { - assert(Parser->TemplateParams.size() >= OldNumTemplateParamLists); - Parser->TemplateParams.dropBack(OldNumTemplateParamLists); - } - }; - - // Template parameter table. Like the above, but referenced like "T42_". - // This has a smaller size compared to Subs and Names because it can be - // stored on the stack. - TemplateParamList OuterTemplateParams; - - // Lists of template parameters indexed by template parameter depth, - // referenced like "TL2_4_". If nonempty, element 0 is always - // OuterTemplateParams; inner elements are always template parameter lists of - // lambda expressions. For a generic lambda with no explicit template - // parameter list, the corresponding parameter list pointer will be null. - PODSmallVector TemplateParams; - - // Set of unresolved forward references. These can occur in a - // conversion operator's type, and are resolved in the enclosing . - PODSmallVector ForwardTemplateRefs; - - bool TryToParseTemplateArgs = true; - bool PermitForwardTemplateReferences = false; - size_t ParsingLambdaParamsAtLevel = (size_t)-1; - - unsigned NumSyntheticTemplateParameters[3] = {}; - - Alloc ASTAllocator; - - AbstractManglingParser(const char *First_, const char *Last_) - : First(First_), Last(Last_) {} - - Derived &getDerived() { return static_cast(*this); } - - void reset(const char *First_, const char *Last_) { - First = First_; - Last = Last_; - Names.clear(); - Subs.clear(); - TemplateParams.clear(); - ParsingLambdaParamsAtLevel = (size_t)-1; - TryToParseTemplateArgs = true; - PermitForwardTemplateReferences = false; - for (int I = 0; I != 3; ++I) - NumSyntheticTemplateParameters[I] = 0; - ASTAllocator.reset(); - } - - template Node *make(Args &&... args) { - return ASTAllocator.template makeNode(std::forward(args)...); - } - - template NodeArray makeNodeArray(It begin, It end) { - size_t sz = static_cast(end - begin); - void *mem = ASTAllocator.allocateNodeArray(sz); - Node **data = new (mem) Node *[sz]; - std::copy(begin, end, data); - return NodeArray(data, sz); - } - - NodeArray popTrailingNodeArray(size_t FromPosition) { - assert(FromPosition <= Names.size()); - NodeArray res = - makeNodeArray(Names.begin() + (long)FromPosition, Names.end()); - Names.dropBack(FromPosition); - return res; - } - - bool consumeIf(StringView S) { - if (StringView(First, Last).startsWith(S)) { - First += S.size(); - return true; - } - return false; - } - - bool consumeIf(char C) { - if (First != Last && *First == C) { - ++First; - return true; - } - return false; - } - - char consume() { return First != Last ? *First++ : '\0'; } - - char look(unsigned Lookahead = 0) const { - if (static_cast(Last - First) <= Lookahead) - return '\0'; - return First[Lookahead]; - } - - size_t numLeft() const { return static_cast(Last - First); } - - StringView parseNumber(bool AllowNegative = false); - Qualifiers parseCVQualifiers(); - bool parsePositiveInteger(size_t *Out); - StringView parseBareSourceName(); - - bool parseSeqId(size_t *Out); - Node *parseSubstitution(); - Node *parseTemplateParam(); - Node *parseTemplateParamDecl(); - Node *parseTemplateArgs(bool TagTemplates = false); - Node *parseTemplateArg(); - - /// Parse the production. - Node *parseExpr(); - Node *parsePrefixExpr(StringView Kind, Node::Prec Prec); - Node *parseBinaryExpr(StringView Kind, Node::Prec Prec); - Node *parseIntegerLiteral(StringView Lit); - Node *parseExprPrimary(); - template Node *parseFloatingLiteral(); - Node *parseFunctionParam(); - Node *parseConversionExpr(); - Node *parseBracedExpr(); - Node *parseFoldExpr(); - Node *parsePointerToMemberConversionExpr(Node::Prec Prec); - Node *parseSubobjectExpr(); - - /// Parse the production. - Node *parseType(); - Node *parseFunctionType(); - Node *parseVectorType(); - Node *parseDecltype(); - Node *parseArrayType(); - Node *parsePointerToMemberType(); - Node *parseClassEnumType(); - Node *parseQualifiedType(); - - Node *parseEncoding(); - bool parseCallOffset(); - Node *parseSpecialName(); - - /// Holds some extra information about a that is being parsed. This - /// information is only pertinent if the refers to an . - struct NameState { - bool CtorDtorConversion = false; - bool EndsWithTemplateArgs = false; - Qualifiers CVQualifiers = QualNone; - FunctionRefQual ReferenceQualifier = FrefQualNone; - size_t ForwardTemplateRefsBegin; - - NameState(AbstractManglingParser *Enclosing) - : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {} - }; - - bool resolveForwardTemplateRefs(NameState &State) { - size_t I = State.ForwardTemplateRefsBegin; - size_t E = ForwardTemplateRefs.size(); - for (; I < E; ++I) { - size_t Idx = ForwardTemplateRefs[I]->Index; - if (TemplateParams.empty() || !TemplateParams[0] || - Idx >= TemplateParams[0]->size()) - return true; - ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx]; - } - ForwardTemplateRefs.dropBack(State.ForwardTemplateRefsBegin); - return false; - } - - /// Parse the production> - Node *parseName(NameState *State = nullptr); - Node *parseLocalName(NameState *State); - Node *parseOperatorName(NameState *State); - bool parseModuleNameOpt(ModuleName *&Module); - Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module); - Node *parseUnnamedTypeName(NameState *State); - Node *parseSourceName(NameState *State); - Node *parseUnscopedName(NameState *State, bool *isSubstName); - Node *parseNestedName(NameState *State); - Node *parseCtorDtorName(Node *&SoFar, NameState *State); - - Node *parseAbiTags(Node *N); - - struct OperatorInfo { - enum OIKind : unsigned char { - Prefix, // Prefix unary: @ expr - Postfix, // Postfix unary: expr @ - Binary, // Binary: lhs @ rhs - Array, // Array index: lhs [ rhs ] - Member, // Member access: lhs @ rhs - New, // New - Del, // Delete - Call, // Function call: expr (expr*) - CCast, // C cast: (type)expr - Conditional, // Conditional: expr ? expr : expr - NameOnly, // Overload only, not allowed in expression. - // Below do not have operator names - NamedCast, // Named cast, @(expr) - OfIdOp, // alignof, sizeof, typeid - - Unnameable = NamedCast, - }; - char Enc[2]; // Encoding - OIKind Kind; // Kind of operator - bool Flag : 1; // Entry-specific flag - Node::Prec Prec : 7; // Precedence - const char *Name; // Spelling - - public: - constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P, - const char *N) - : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {} - - public: - bool operator<(const OperatorInfo &Other) const { - return *this < Other.Enc; - } - bool operator<(const char *Peek) const { - return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]); - } - bool operator==(const char *Peek) const { - return Enc[0] == Peek[0] && Enc[1] == Peek[1]; - } - bool operator!=(const char *Peek) const { return !this->operator==(Peek); } - - public: - StringView getSymbol() const { - StringView Res = Name; - if (Kind < Unnameable) { - assert(Res.startsWith("operator") && - "operator name does not start with 'operator'"); - Res = Res.dropFront(sizeof("operator") - 1); - Res.consumeFront(' '); - } - return Res; - } - StringView getName() const { return Name; } - OIKind getKind() const { return Kind; } - bool getFlag() const { return Flag; } - Node::Prec getPrecedence() const { return Prec; } - }; - static const OperatorInfo Ops[]; - static const size_t NumOps; - const OperatorInfo *parseOperatorEncoding(); - - /// Parse the production. - Node *parseUnresolvedName(bool Global); - Node *parseSimpleId(); - Node *parseBaseUnresolvedName(); - Node *parseUnresolvedType(); - Node *parseDestructorName(); - - /// Top-level entry point into the parser. - Node *parse(); -}; - -const char* parse_discriminator(const char* first, const char* last); - -// ::= // N -// ::= # See Scope Encoding below // Z -// ::= -// ::= -// -// ::= -// ::= -template -Node *AbstractManglingParser::parseName(NameState *State) { - if (look() == 'N') - return getDerived().parseNestedName(State); - if (look() == 'Z') - return getDerived().parseLocalName(State); - - Node *Result = nullptr; - bool IsSubst = false; - - Result = getDerived().parseUnscopedName(State, &IsSubst); - if (!Result) - return nullptr; - - if (look() == 'I') { - // ::= - if (!IsSubst) - // An unscoped-template-name is substitutable. - Subs.push_back(Result); - Node *TA = getDerived().parseTemplateArgs(State != nullptr); - if (TA == nullptr) - return nullptr; - if (State) - State->EndsWithTemplateArgs = true; - Result = make(Result, TA); - } else if (IsSubst) { - // The substitution case must be followed by . - return nullptr; - } - - return Result; -} - -// := Z E [] -// := Z E s [] -// := Z Ed [ ] _ -template -Node *AbstractManglingParser::parseLocalName(NameState *State) { - if (!consumeIf('Z')) - return nullptr; - Node *Encoding = getDerived().parseEncoding(); - if (Encoding == nullptr || !consumeIf('E')) - return nullptr; - - if (consumeIf('s')) { - First = parse_discriminator(First, Last); - auto *StringLitName = make("string literal"); - if (!StringLitName) - return nullptr; - return make(Encoding, StringLitName); - } - - if (consumeIf('d')) { - parseNumber(true); - if (!consumeIf('_')) - return nullptr; - Node *N = getDerived().parseName(State); - if (N == nullptr) - return nullptr; - return make(Encoding, N); - } - - Node *Entity = getDerived().parseName(State); - if (Entity == nullptr) - return nullptr; - First = parse_discriminator(First, Last); - return make(Encoding, Entity); -} - -// ::= -// ::= St # ::std:: -// [*] extension -template -Node * -AbstractManglingParser::parseUnscopedName(NameState *State, - bool *IsSubst) { - - Node *Std = nullptr; - if (consumeIf("St")) { - Std = make("std"); - if (Std == nullptr) - return nullptr; - } - - Node *Res = nullptr; - ModuleName *Module = nullptr; - if (look() == 'S') { - Node *S = getDerived().parseSubstitution(); - if (!S) - return nullptr; - if (S->getKind() == Node::KModuleName) - Module = static_cast(S); - else if (IsSubst && Std == nullptr) { - Res = S; - *IsSubst = true; - } else { - return nullptr; - } - } - - if (Res == nullptr || Std != nullptr) { - Res = getDerived().parseUnqualifiedName(State, Std, Module); - } - - return Res; -} - -// ::= [] L? [] -// ::= [] [] -// ::= [] L? [] -// ::= [] L? [] -// # structured binding declaration -// ::= [] L? DC + E -template -Node *AbstractManglingParser::parseUnqualifiedName( - NameState *State, Node *Scope, ModuleName *Module) { - if (getDerived().parseModuleNameOpt(Module)) - return nullptr; - - consumeIf('L'); - - Node *Result; - if (look() >= '1' && look() <= '9') { - Result = getDerived().parseSourceName(State); - } else if (look() == 'U') { - Result = getDerived().parseUnnamedTypeName(State); - } else if (consumeIf("DC")) { - // Structured binding - size_t BindingsBegin = Names.size(); - do { - Node *Binding = getDerived().parseSourceName(State); - if (Binding == nullptr) - return nullptr; - Names.push_back(Binding); - } while (!consumeIf('E')); - Result = make(popTrailingNodeArray(BindingsBegin)); - } else if (look() == 'C' || look() == 'D') { - // A . - if (Scope == nullptr || Module != nullptr) - return nullptr; - Result = getDerived().parseCtorDtorName(Scope, State); - } else { - Result = getDerived().parseOperatorName(State); - } - - if (Result != nullptr && Module != nullptr) - Result = make(Module, Result); - if (Result != nullptr) - Result = getDerived().parseAbiTags(Result); - if (Result != nullptr && Scope != nullptr) - Result = make(Scope, Result); - - return Result; -} - -// ::= -// ::= -// ::= # passed in by caller -// ::= W -// ::= W P -template -bool AbstractManglingParser::parseModuleNameOpt( - ModuleName *&Module) { - while (consumeIf('W')) { - bool IsPartition = consumeIf('P'); - Node *Sub = getDerived().parseSourceName(nullptr); - if (!Sub) - return true; - Module = - static_cast(make(Module, Sub, IsPartition)); - Subs.push_back(Module); - } - - return false; -} - -// ::= Ut [] _ -// ::= -// -// ::= Ul E [ ] _ -// -// ::= + # Parameter types or "v" if the lambda has no parameters -template -Node * -AbstractManglingParser::parseUnnamedTypeName(NameState *State) { - // refer to the innermost . Clear out any - // outer args that we may have inserted into TemplateParams. - if (State != nullptr) - TemplateParams.clear(); - - if (consumeIf("Ut")) { - StringView Count = parseNumber(); - if (!consumeIf('_')) - return nullptr; - return make(Count); - } - if (consumeIf("Ul")) { - ScopedOverride SwapParams(ParsingLambdaParamsAtLevel, - TemplateParams.size()); - ScopedTemplateParamList LambdaTemplateParams(this); - - size_t ParamsBegin = Names.size(); - while (look() == 'T' && - StringView("yptn").find(look(1)) != StringView::npos) { - Node *T = parseTemplateParamDecl(); - if (!T) - return nullptr; - Names.push_back(T); - } - NodeArray TempParams = popTrailingNodeArray(ParamsBegin); - - // FIXME: If TempParams is empty and none of the function parameters - // includes 'auto', we should remove LambdaTemplateParams from the - // TemplateParams list. Unfortunately, we don't find out whether there are - // any 'auto' parameters until too late in an example such as: - // - // template void f( - // decltype([](decltype([](T v) {}), - // auto) {})) {} - // template void f( - // decltype([](decltype([](T w) {}), - // int) {})) {} - // - // Here, the type of v is at level 2 but the type of w is at level 1. We - // don't find this out until we encounter the type of the next parameter. - // - // However, compilers can't actually cope with the former example in - // practice, and it's likely to be made ill-formed in future, so we don't - // need to support it here. - // - // If we encounter an 'auto' in the function parameter types, we will - // recreate a template parameter scope for it, but any intervening lambdas - // will be parsed in the 'wrong' template parameter depth. - if (TempParams.empty()) - TemplateParams.pop_back(); - - if (!consumeIf("vE")) { - do { - Node *P = getDerived().parseType(); - if (P == nullptr) - return nullptr; - Names.push_back(P); - } while (!consumeIf('E')); - } - NodeArray Params = popTrailingNodeArray(ParamsBegin); - - StringView Count = parseNumber(); - if (!consumeIf('_')) - return nullptr; - return make(TempParams, Params, Count); - } - if (consumeIf("Ub")) { - (void)parseNumber(); - if (!consumeIf('_')) - return nullptr; - return make("'block-literal'"); - } - return nullptr; -} - -// ::= -template -Node *AbstractManglingParser::parseSourceName(NameState *) { - size_t Length = 0; - if (parsePositiveInteger(&Length)) - return nullptr; - if (numLeft() < Length || Length == 0) - return nullptr; - StringView Name(First, First + Length); - First += Length; - if (Name.startsWith("_GLOBAL__N")) - return make("(anonymous namespace)"); - return make(Name); -} - -// Operator encodings -template -const typename AbstractManglingParser< - Derived, Alloc>::OperatorInfo AbstractManglingParser::Ops[] = { - // Keep ordered by encoding - {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="}, - {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="}, - {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"}, - {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"}, - {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"}, - {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "}, - {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary, - "operator co_await"}, - {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "}, - {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"}, - {"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"}, - {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"}, - {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"}, - {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast - {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="}, - {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary, - "operator delete[]"}, - {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"}, - {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"}, - {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary, - "operator delete"}, - {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem, - "operator.*"}, - {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix, - "operator."}, - {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"}, - {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="}, - {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"}, - {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="}, - {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="}, - {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"}, - {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"}, - {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="}, - {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="}, - {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"}, - {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"}, - {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="}, - {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="}, - {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"}, - {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative, - "operator*"}, - {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"}, - {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary, - "operator new[]"}, - {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="}, - {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"}, - {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"}, - {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"}, - {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="}, - {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"}, - {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"}, - {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="}, - {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"}, - {"pm", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem, - "operator->*"}, - {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"}, - {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"}, - {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix, - "operator->"}, - {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional, - "operator?"}, - {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="}, - {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="}, - {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, - "reinterpret_cast"}, - {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative, - "operator%"}, - {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"}, - {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"}, - {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"}, - {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "}, - {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "}, - {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix, - "typeid "}, - {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "}, -}; -template -const size_t AbstractManglingParser::NumOps = sizeof(Ops) / - sizeof(Ops[0]); - -// If the next 2 chars are an operator encoding, consume them and return their -// OperatorInfo. Otherwise return nullptr. -template -const typename AbstractManglingParser::OperatorInfo * -AbstractManglingParser::parseOperatorEncoding() { - if (numLeft() < 2) - return nullptr; - - // We can't use lower_bound as that can link to symbols in the C++ library, - // and this must remain independant of that. - size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds. - while (upper != lower) { - size_t middle = (upper + lower) / 2; - if (Ops[middle] < First) - lower = middle + 1; - else - upper = middle; - } - if (Ops[lower] != First) - return nullptr; - - First += 2; - return &Ops[lower]; -} - -// ::= See parseOperatorEncoding() -// ::= li # operator "" -// ::= v # vendor extended operator -template -Node * -AbstractManglingParser::parseOperatorName(NameState *State) { - if (const auto *Op = parseOperatorEncoding()) { - if (Op->getKind() == OperatorInfo::CCast) { - // ::= cv # (cast) - ScopedOverride SaveTemplate(TryToParseTemplateArgs, false); - // If we're parsing an encoding, State != nullptr and the conversion - // operators' could have a that refers to some - // s further ahead in the mangled name. - ScopedOverride SavePermit(PermitForwardTemplateReferences, - PermitForwardTemplateReferences || - State != nullptr); - Node *Ty = getDerived().parseType(); - if (Ty == nullptr) - return nullptr; - if (State) State->CtorDtorConversion = true; - return make(Ty); - } - - if (Op->getKind() >= OperatorInfo::Unnameable) - /* Not a nameable operator. */ - return nullptr; - if (Op->getKind() == OperatorInfo::Member && !Op->getFlag()) - /* Not a nameable MemberExpr */ - return nullptr; - - return make(Op->getName()); - } - - if (consumeIf("li")) { - // ::= li # operator "" - Node *SN = getDerived().parseSourceName(State); - if (SN == nullptr) - return nullptr; - return make(SN); - } - - if (consumeIf('v')) { - // ::= v # vendor extended operator - if (look() >= '0' && look() <= '9') { - First++; - Node *SN = getDerived().parseSourceName(State); - if (SN == nullptr) - return nullptr; - return make(SN); - } - return nullptr; - } - - return nullptr; -} - -// ::= C1 # complete object constructor -// ::= C2 # base object constructor -// ::= C3 # complete object allocating constructor -// extension ::= C4 # gcc old-style "[unified]" constructor -// extension ::= C5 # the COMDAT used for ctors -// ::= D0 # deleting destructor -// ::= D1 # complete object destructor -// ::= D2 # base object destructor -// extension ::= D4 # gcc old-style "[unified]" destructor -// extension ::= D5 # the COMDAT used for dtors -template -Node * -AbstractManglingParser::parseCtorDtorName(Node *&SoFar, - NameState *State) { - if (SoFar->getKind() == Node::KSpecialSubstitution) { - // Expand the special substitution. - SoFar = make( - static_cast(SoFar)); - if (!SoFar) - return nullptr; - } - - if (consumeIf('C')) { - bool IsInherited = consumeIf('I'); - if (look() != '1' && look() != '2' && look() != '3' && look() != '4' && - look() != '5') - return nullptr; - int Variant = look() - '0'; - ++First; - if (State) State->CtorDtorConversion = true; - if (IsInherited) { - if (getDerived().parseName(State) == nullptr) - return nullptr; - } - return make(SoFar, /*IsDtor=*/false, Variant); - } - - if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' || - look(1) == '4' || look(1) == '5')) { - int Variant = look(1) - '0'; - First += 2; - if (State) State->CtorDtorConversion = true; - return make(SoFar, /*IsDtor=*/true, Variant); - } - - return nullptr; -} - -// ::= N [] [] -// E -// ::= N [] [] -// E -// -// ::= -// ::= -// ::= -// ::= -// ::= # empty -// ::= -// ::= -// [*] extension -// -// := [] M -// -// ::=