Commit 7ab01c9a42
Changed files (18)
lib
libcxxabi
include
src
lib/libcxxabi/include/__cxxabi_config.h
@@ -103,4 +103,10 @@
#define _LIBCXXABI_DTOR_FUNC
#endif
+#if __cplusplus < 201103L
+# define _LIBCXXABI_NOEXCEPT throw()
+#else
+# define _LIBCXXABI_NOEXCEPT noexcept
+#endif
+
#endif // ____CXXABI_CONFIG_H
lib/libcxxabi/include/cxxabi.h
@@ -43,16 +43,16 @@ extern "C" {
// 2.4.2 Allocating the Exception Object
extern _LIBCXXABI_FUNC_VIS void *
-__cxa_allocate_exception(size_t thrown_size) throw();
+__cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void
-__cxa_free_exception(void *thrown_exception) throw();
+__cxa_free_exception(void *thrown_exception) _LIBCXXABI_NOEXCEPT;
// This function is an LLVM extension, which mirrors the same extension in libsupc++ and libcxxrt
extern _LIBCXXABI_FUNC_VIS __cxa_exception*
#ifdef __wasm__
// In Wasm, a destructor returns its argument
-__cxa_init_primary_exception(void* object, std::type_info* tinfo, void*(_LIBCXXABI_DTOR_FUNC* dest)(void*)) throw();
+__cxa_init_primary_exception(void* object, std::type_info* tinfo, void*(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
#else
-__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) throw();
+__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
#endif
// 2.4.3 Throwing the Exception Object
@@ -66,13 +66,13 @@ __cxa_throw(void *thrown_exception, std::type_info *tinfo,
// 2.5.3 Exception Handlers
extern _LIBCXXABI_FUNC_VIS void *
-__cxa_get_exception_ptr(void *exceptionObject) throw();
+__cxa_get_exception_ptr(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void *
-__cxa_begin_catch(void *exceptionObject) throw();
+__cxa_begin_catch(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch();
#if defined(_LIBCXXABI_ARM_EHABI)
extern _LIBCXXABI_FUNC_VIS bool
-__cxa_begin_cleanup(void *exceptionObject) throw();
+__cxa_begin_cleanup(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void __cxa_end_cleanup();
#endif
extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
@@ -80,7 +80,7 @@ extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
// GNU extension
// Calls `terminate` with the current exception being caught. This function is used by GCC when a `noexcept` function
// throws an exception inside a try/catch block and doesn't catch it.
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_call_terminate(void*) throw();
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_call_terminate(void*) _LIBCXXABI_NOEXCEPT;
// 2.5.4 Rethrowing Exceptions
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_rethrow();
@@ -168,23 +168,23 @@ extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
// Apple additions to support C++ 0x exception_ptr class
// These are primitives to wrap a smart pointer around an exception object
-extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() throw();
+extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void
__cxa_rethrow_primary_exception(void *primary_exception);
extern _LIBCXXABI_FUNC_VIS void
-__cxa_increment_exception_refcount(void *primary_exception) throw();
+__cxa_increment_exception_refcount(void *primary_exception) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void
-__cxa_decrement_exception_refcount(void *primary_exception) throw();
+__cxa_decrement_exception_refcount(void *primary_exception) _LIBCXXABI_NOEXCEPT;
// Apple extension to support std::uncaught_exception()
-extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() throw();
-extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() throw();
+extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _LIBCXXABI_NOEXCEPT;
+extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _LIBCXXABI_NOEXCEPT;
#if defined(__linux__) || defined(__Fuchsia__)
// Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI.
// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
extern _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*)(void *), void *,
- void *) throw();
+ void *) _LIBCXXABI_NOEXCEPT;
#endif
} // extern "C"
lib/libcxxabi/src/demangle/DemangleConfig.h
@@ -15,7 +15,7 @@
// build systems to override this value.
// https://libcxx.llvm.org/UsingLibcxx.html#enabling-the-safe-libc-mode
#ifndef _LIBCPP_VERBOSE_ABORT
-#define _LIBCPP_VERBOSE_ABORT(...) abort_message(__VA_ARGS__)
+#define _LIBCPP_VERBOSE_ABORT(...) __abort_message(__VA_ARGS__)
#include "../abort_message.h"
#endif
lib/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -19,7 +19,6 @@
#include "DemangleConfig.h"
#include "StringViewExtras.h"
#include "Utility.h"
-#include <__cxxabi_config.h>
#include <algorithm>
#include <cctype>
#include <cstdio>
@@ -31,7 +30,7 @@
#include <type_traits>
#include <utility>
-#ifdef _LIBCXXABI_COMPILER_CLANG
+#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-template"
#endif
@@ -157,6 +156,8 @@ public:
}
};
+class NodeArray;
+
// 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 {
@@ -200,8 +201,7 @@ private:
Prec Precedence : 6;
- // FIXME: Make these protected.
-public:
+protected:
/// Tracks if this node has a component on its right side, in which case we
/// need to call printRight.
Cache RHSComponentCache : 2;
@@ -255,6 +255,9 @@ public:
Kind getKind() const { return K; }
Prec getPrecedence() const { return Precedence; }
+ Cache getRHSComponentCache() const { return RHSComponentCache; }
+ Cache getArrayCache() const { return ArrayCache; }
+ Cache getFunctionCache() const { return FunctionCache; }
virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
virtual bool hasArraySlow(OutputBuffer &) const { return false; }
@@ -292,6 +295,13 @@ public:
// implementation.
virtual void printRight(OutputBuffer &) const {}
+ // Print an initializer list of this type. Returns true if we printed a custom
+ // representation, false if nothing has been printed and the default
+ // representation should be used.
+ virtual bool printInitListAsType(OutputBuffer &, const NodeArray &) const {
+ return false;
+ }
+
virtual std::string_view getBaseName() const { return {}; }
// Silence compiler warnings, this dtor will never be called.
@@ -338,6 +348,10 @@ public:
FirstElement = false;
}
}
+
+ // Print an array of integer literals as a string literal. Returns whether we
+ // could do so.
+ bool printAsString(OutputBuffer &OB) const;
};
struct NodeArrayNode : Node {
@@ -424,8 +438,8 @@ protected:
public:
QualType(const Node *Child_, Qualifiers Quals_)
- : Node(KQualType, Child_->RHSComponentCache,
- Child_->ArrayCache, Child_->FunctionCache),
+ : Node(KQualType, Child_->getRHSComponentCache(), Child_->getArrayCache(),
+ Child_->getFunctionCache()),
Quals(Quals_), Child(Child_) {}
Qualifiers getQuals() const { return Quals; }
@@ -554,8 +568,8 @@ struct AbiTagAttr : Node {
std::string_view Tag;
AbiTagAttr(Node *Base_, std::string_view Tag_)
- : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
- Base_->FunctionCache),
+ : Node(KAbiTagAttr, Base_->getRHSComponentCache(), Base_->getArrayCache(),
+ Base_->getFunctionCache()),
Base(Base_), Tag(Tag_) {}
template<typename Fn> void match(Fn F) const { F(Base, Tag); }
@@ -615,7 +629,7 @@ class PointerType final : public Node {
public:
PointerType(const Node *Pointee_)
- : Node(KPointerType, Pointee_->RHSComponentCache),
+ : Node(KPointerType, Pointee_->getRHSComponentCache()),
Pointee(Pointee_) {}
const Node *getPointee() const { return Pointee; }
@@ -699,7 +713,7 @@ class ReferenceType : public Node {
public:
ReferenceType(const Node *Pointee_, ReferenceKind RK_)
- : Node(KReferenceType, Pointee_->RHSComponentCache),
+ : Node(KReferenceType, Pointee_->getRHSComponentCache()),
Pointee(Pointee_), RK(RK_) {}
template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
@@ -742,7 +756,7 @@ class PointerToMemberType final : public Node {
public:
PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
- : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
+ : Node(KPointerToMemberType, MemberType_->getRHSComponentCache()),
ClassType(ClassType_), MemberType(MemberType_) {}
template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
@@ -795,6 +809,15 @@ public:
OB += "]";
Base->printRight(OB);
}
+
+ bool printInitListAsType(OutputBuffer &OB,
+ const NodeArray &Elements) const override {
+ if (Base->getKind() == KNameType &&
+ static_cast<const NameType *>(Base)->getName() == "char") {
+ return Elements.printAsString(OB);
+ }
+ return false;
+ }
};
class FunctionType final : public Node {
@@ -1383,16 +1406,14 @@ class ParameterPack final : public Node {
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;
- }))
+ if (std::all_of(Data.begin(), Data.end(),
+ [](Node *P) { return P->getArrayCache() == Cache::No; }))
ArrayCache = Cache::No;
- if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
- return P->FunctionCache == Cache::No;
- }))
+ if (std::all_of(Data.begin(), Data.end(),
+ [](Node *P) { return P->getFunctionCache() == Cache::No; }))
FunctionCache = Cache::No;
- if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
- return P->RHSComponentCache == Cache::No;
+ if (std::all_of(Data.begin(), Data.end(), [](Node *P) {
+ return P->getRHSComponentCache() == Cache::No;
}))
RHSComponentCache = Cache::No;
}
@@ -2056,17 +2077,23 @@ public:
class CallExpr : public Node {
const Node *Callee;
NodeArray Args;
+ bool IsParen; // (func)(args ...) ?
public:
- CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
- : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
+ CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
+ : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
+ IsParen(IsParen_) {}
template <typename Fn> void match(Fn F) const {
- F(Callee, Args, getPrecedence());
+ F(Callee, Args, IsParen, getPrecedence());
}
void printLeft(OutputBuffer &OB) const override {
+ if (IsParen)
+ OB.printOpen();
Callee->print(OB);
+ if (IsParen)
+ OB.printClose();
OB.printOpen();
Args.printWithComma(OB);
OB.printClose();
@@ -2226,8 +2253,11 @@ public:
template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
void printLeft(OutputBuffer &OB) const override {
- if (Ty)
+ if (Ty) {
+ if (Ty->printInitListAsType(OB, Inits))
+ return;
Ty->print(OB);
+ }
OB += '{';
Inits.printWithComma(OB);
OB += '}';
@@ -2434,6 +2464,8 @@ public:
if (Type.size() <= 3)
OB += Type;
}
+
+ std::string_view value() const { return Value; }
};
class RequiresExpr : public Node {
@@ -2605,6 +2637,94 @@ template<typename NodeT> struct NodeKind;
};
#include "ItaniumNodes.def"
+inline bool NodeArray::printAsString(OutputBuffer &OB) const {
+ auto StartPos = OB.getCurrentPosition();
+ auto Fail = [&OB, StartPos] {
+ OB.setCurrentPosition(StartPos);
+ return false;
+ };
+
+ OB += '"';
+ bool LastWasNumericEscape = false;
+ for (const Node *Element : *this) {
+ if (Element->getKind() != Node::KIntegerLiteral)
+ return Fail();
+ int integer_value = 0;
+ for (char c : static_cast<const IntegerLiteral *>(Element)->value()) {
+ if (c < '0' || c > '9' || integer_value > 25)
+ return Fail();
+ integer_value *= 10;
+ integer_value += c - '0';
+ }
+ if (integer_value > 255)
+ return Fail();
+
+ // Insert a `""` to avoid accidentally extending a numeric escape.
+ if (LastWasNumericEscape) {
+ if ((integer_value >= '0' && integer_value <= '9') ||
+ (integer_value >= 'a' && integer_value <= 'f') ||
+ (integer_value >= 'A' && integer_value <= 'F')) {
+ OB += "\"\"";
+ }
+ }
+
+ LastWasNumericEscape = false;
+
+ // Determine how to print this character.
+ switch (integer_value) {
+ case '\a':
+ OB += "\\a";
+ break;
+ case '\b':
+ OB += "\\b";
+ break;
+ case '\f':
+ OB += "\\f";
+ break;
+ case '\n':
+ OB += "\\n";
+ break;
+ case '\r':
+ OB += "\\r";
+ break;
+ case '\t':
+ OB += "\\t";
+ break;
+ case '\v':
+ OB += "\\v";
+ break;
+
+ case '"':
+ OB += "\\\"";
+ break;
+ case '\\':
+ OB += "\\\\";
+ break;
+
+ default:
+ // We assume that the character is ASCII, and use a numeric escape for all
+ // remaining non-printable ASCII characters.
+ if (integer_value < 32 || integer_value == 127) {
+ constexpr char Hex[] = "0123456789ABCDEF";
+ OB += '\\';
+ if (integer_value > 7)
+ OB += 'x';
+ if (integer_value >= 16)
+ OB += Hex[integer_value >> 4];
+ OB += Hex[integer_value & 0xF];
+ LastWasNumericEscape = true;
+ break;
+ }
+
+ // Assume all remaining characters are directly printable.
+ OB += (char)integer_value;
+ break;
+ }
+ }
+ OB += '"';
+ return true;
+}
+
template <typename Derived, typename Alloc> struct AbstractManglingParser {
const char *First;
const char *Last;
@@ -2678,7 +2798,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
bool TryToParseTemplateArgs = true;
bool PermitForwardTemplateReferences = false;
- bool InConstraintExpr = false;
+ bool HasIncompleteTemplateParameterTracking = false;
size_t ParsingLambdaParamsAtLevel = (size_t)-1;
unsigned NumSyntheticTemplateParameters[3] = {};
@@ -3240,9 +3360,12 @@ const typename AbstractManglingParser<
"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()"},
+ {"cl", OperatorInfo::Call, /*Paren*/ false, Node::Prec::Postfix,
+ "operator()"},
{"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
{"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
+ {"cp", OperatorInfo::Call, /*Paren*/ true, Node::Prec::Postfix,
+ "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,
@@ -3319,7 +3442,7 @@ AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
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.
+ // and this must remain independent of that.
size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
while (upper != lower) {
size_t middle = (upper + lower) / 2;
@@ -4207,9 +4330,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
case 'h':
First += 2;
return make<NameType>("half");
- // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
+ // ::= DF16b # C++23 std::bfloat16_t
+ // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
case 'F': {
First += 2;
+ if (consumeIf("16b"))
+ return make<NameType>("std::bfloat16_t");
Node *DimensionNumber = make<NameType>(parseNumber());
if (!DimensionNumber)
return nullptr;
@@ -4217,6 +4343,101 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
return nullptr;
return make<BinaryFPType>(DimensionNumber);
}
+ // ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum
+ // ::= [DS] DR # N1169 fixed-point [_Sat] T _Frac
+ // <fixed-point-size>
+ // ::= s # short
+ // ::= t # unsigned short
+ // ::= i # plain
+ // ::= j # unsigned
+ // ::= l # long
+ // ::= m # unsigned long
+ case 'A': {
+ char c = look(2);
+ First += 3;
+ switch (c) {
+ case 's':
+ return make<NameType>("short _Accum");
+ case 't':
+ return make<NameType>("unsigned short _Accum");
+ case 'i':
+ return make<NameType>("_Accum");
+ case 'j':
+ return make<NameType>("unsigned _Accum");
+ case 'l':
+ return make<NameType>("long _Accum");
+ case 'm':
+ return make<NameType>("unsigned long _Accum");
+ default:
+ return nullptr;
+ }
+ }
+ case 'R': {
+ char c = look(2);
+ First += 3;
+ switch (c) {
+ case 's':
+ return make<NameType>("short _Fract");
+ case 't':
+ return make<NameType>("unsigned short _Fract");
+ case 'i':
+ return make<NameType>("_Fract");
+ case 'j':
+ return make<NameType>("unsigned _Fract");
+ case 'l':
+ return make<NameType>("long _Fract");
+ case 'm':
+ return make<NameType>("unsigned long _Fract");
+ default:
+ return nullptr;
+ }
+ }
+ case 'S': {
+ First += 2;
+ if (look() != 'D')
+ return nullptr;
+ if (look(1) == 'A') {
+ char c = look(2);
+ First += 3;
+ switch (c) {
+ case 's':
+ return make<NameType>("_Sat short _Accum");
+ case 't':
+ return make<NameType>("_Sat unsigned short _Accum");
+ case 'i':
+ return make<NameType>("_Sat _Accum");
+ case 'j':
+ return make<NameType>("_Sat unsigned _Accum");
+ case 'l':
+ return make<NameType>("_Sat long _Accum");
+ case 'm':
+ return make<NameType>("_Sat unsigned long _Accum");
+ default:
+ return nullptr;
+ }
+ }
+ if (look(1) == 'R') {
+ char c = look(2);
+ First += 3;
+ switch (c) {
+ case 's':
+ return make<NameType>("_Sat short _Fract");
+ case 't':
+ return make<NameType>("_Sat unsigned short _Fract");
+ case 'i':
+ return make<NameType>("_Sat _Fract");
+ case 'j':
+ return make<NameType>("_Sat unsigned _Fract");
+ case 'l':
+ return make<NameType>("_Sat long _Fract");
+ case 'm':
+ return make<NameType>("_Sat unsigned long _Fract");
+ default:
+ return nullptr;
+ }
+ }
+ return nullptr;
+ }
// ::= DB <number> _ # C23 signed _BitInt(N)
// ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
// ::= DU <number> _ # C23 unsigned _BitInt(N)
@@ -4337,6 +4558,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
// parse them, take the second production.
if (TryToParseTemplateArgs && look() == 'I') {
+ Subs.push_back(Result);
Node *TA = getDerived().parseTemplateArgs();
if (TA == nullptr)
return nullptr;
@@ -4819,7 +5041,8 @@ template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
// Within this expression, all enclosing template parameter lists are in
// scope.
- ScopedOverride<bool> SaveInConstraintExpr(InConstraintExpr, true);
+ ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
+ HasIncompleteTemplateParameterTracking, true);
return getDerived().parseExpr();
}
@@ -4888,6 +5111,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
// ::= <binary operator-name> <expression> <expression>
// ::= <ternary operator-name> <expression> <expression> <expression>
// ::= cl <expression>+ E # call
+// ::= cp <base-unresolved-name> <expression>* E # (name) (expr-list), call that would use argument-dependent lookup but for the parentheses
// ::= cv <type> <expression> # conversion with one argument
// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
@@ -5023,7 +5247,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
Names.push_back(E);
}
return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
- Op->getPrecedence());
+ /*IsParen=*/Op->getFlag(), Op->getPrecedence());
}
case OperatorInfo::CCast: {
// C Cast: (type)expr
@@ -5210,7 +5434,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
}
}
return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
- Node::Prec::Postfix);
+ /*IsParen=*/false, Node::Prec::Postfix);
}
// Only unresolved names remain.
@@ -5677,7 +5901,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
// substitute them all within a <constraint-expression>, so print the
// parameter numbering instead for now.
// TODO: Track all enclosing template parameters and substitute them here.
- if (InConstraintExpr) {
+ if (HasIncompleteTemplateParameterTracking) {
return make<NameType>(std::string_view(Begin, First - 1 - Begin));
}
@@ -5738,6 +5962,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
}
if (consumeIf("Tk")) {
+ // We don't track enclosing template parameter levels well enough to
+ // reliably demangle template parameter substitutions, so print an arbitrary
+ // string in place of a parameter for now.
+ // TODO: Track all enclosing template parameters and demangle substitutions.
+ ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
+ HasIncompleteTemplateParameterTracking, true);
Node *Constraint = getDerived().parseName();
if (!Constraint)
return nullptr;
@@ -5948,7 +6178,7 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
DEMANGLE_NAMESPACE_END
-#ifdef _LIBCXXABI_COMPILER_CLANG
+#if defined(__clang__)
#pragma clang diagnostic pop
#endif
lib/libcxxabi/src/abort_message.cpp
@@ -12,13 +12,8 @@
#include "abort_message.h"
#ifdef __BIONIC__
-# include <android/api-level.h>
-# if __ANDROID_API__ >= 21
-# include <syslog.h>
- extern "C" void android_set_abort_message(const char* msg);
-# else
-# include <assert.h>
-# endif // __ANDROID_API__ >= 21
+# include <syslog.h>
+extern "C" void android_set_abort_message(const char* msg);
#endif // __BIONIC__
#if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
@@ -26,7 +21,7 @@
# define _LIBCXXABI_USE_CRASHREPORTER_CLIENT
#endif
-void abort_message(const char* format, ...)
+void __abort_message(const char* format, ...)
{
// Write message to stderr. We do this before formatting into a
// variable-size buffer so that we still get some information if
@@ -59,7 +54,6 @@ void abort_message(const char* format, ...)
vasprintf(&buffer, format, list);
va_end(list);
-# if __ANDROID_API__ >= 21
// Show error in tombstone.
android_set_abort_message(buffer);
@@ -67,12 +61,6 @@ void abort_message(const char* format, ...)
openlog("libc++abi", 0, 0);
syslog(LOG_CRIT, "%s", buffer);
closelog();
-# else
- // The good error reporting wasn't available in Android until L. Since we're
- // about to abort anyway, just call __assert2, which will log _somewhere_
- // (tombstone and/or logcat) in older releases.
- __assert2(__FILE__, __LINE__, __func__, buffer);
-# endif // __ANDROID_API__ >= 21
#endif // __BIONIC__
abort();
lib/libcxxabi/src/abort_message.h
@@ -12,7 +12,7 @@
#include "cxxabi.h"
extern "C" _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
-abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
+__abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
#ifndef _LIBCXXABI_ASSERT
// zig patch: respect NDEBUG. Otherwise the file path makes it into the binary,
@@ -24,7 +24,7 @@ abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
do { \
if (!(expr)) { \
char const* __msg = (msg); \
- ::abort_message("%s:%d: %s", __FILE__, __LINE__, __msg); \
+ ::__abort_message("%s:%d: %s", __FILE__, __LINE__, __msg); \
} \
} while (false)
lib/libcxxabi/src/cxa_default_handlers.cpp
@@ -10,8 +10,7 @@
//===----------------------------------------------------------------------===//
#include <exception>
-#include <memory>
-#include <stdlib.h>
+#include <new>
#include "abort_message.h"
#include "cxxabi.h"
#include "cxa_handlers.h"
@@ -23,17 +22,7 @@
static constinit const char* cause = "uncaught";
-#ifndef _LIBCXXABI_NO_EXCEPTIONS
-// Demangle the given string, or return the string as-is in case of an error.
-static std::unique_ptr<char const, void (*)(char const*)> demangle(char const* str)
-{
-#if !defined(LIBCXXABI_NON_DEMANGLING_TERMINATE)
- if (const char* result = __cxxabiv1::__cxa_demangle(str, nullptr, nullptr, nullptr))
- return {result, [](char const* p) { std::free(const_cast<char*>(p)); }};
-#endif
- return {str, [](char const*) { /* nothing to free */ }};
-}
-
+# ifndef _LIBCXXABI_NO_EXCEPTIONS
__attribute__((noreturn))
static void demangling_terminate_handler()
{
@@ -42,18 +31,18 @@ static void demangling_terminate_handler()
// If there is no uncaught exception, just note that we're terminating
if (!globals)
- abort_message("terminating");
+ __abort_message("terminating");
__cxa_exception* exception_header = globals->caughtExceptions;
if (!exception_header)
- abort_message("terminating");
+ __abort_message("terminating");
_Unwind_Exception* unwind_exception =
reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
// If we're terminating due to a foreign exception
if (!__isOurExceptionClass(unwind_exception))
- abort_message("terminating due to %s foreign exception", cause);
+ __abort_message("terminating due to %s foreign exception", cause);
void* thrown_object =
__getExceptionClass(unwind_exception) == kOurDependentExceptionClass ?
@@ -61,7 +50,17 @@ static void demangling_terminate_handler()
exception_header + 1;
const __shim_type_info* thrown_type =
static_cast<const __shim_type_info*>(exception_header->exceptionType);
- auto name = demangle(thrown_type->name());
+
+ auto name = [str = thrown_type->name()] {
+# ifndef LIBCXXABI_NON_DEMANGLING_TERMINATE
+ if (const char* result = __cxxabiv1::__cxa_demangle(str, nullptr, nullptr, nullptr))
+ // We're about to abort(), this memory can never be freed; so it's fine
+ // to just return a raw pointer
+ return result;
+# endif
+ return str;
+ }();
+
// If the uncaught exception can be caught with std::exception&
const __shim_type_info* catch_type =
static_cast<const __shim_type_info*>(&typeid(std::exception));
@@ -69,19 +68,19 @@ static void demangling_terminate_handler()
{
// Include the what() message from the exception
const std::exception* e = static_cast<const std::exception*>(thrown_object);
- abort_message("terminating due to %s exception of type %s: %s", cause, name.get(), e->what());
+ __abort_message("terminating due to %s exception of type %s: %s", cause, name, e->what());
}
else
{
// Else just note that we're terminating due to an exception
- abort_message("terminating due to %s exception of type %s", cause, name.get());
+ __abort_message("terminating due to %s exception of type %s", cause, name);
}
}
#else // !_LIBCXXABI_NO_EXCEPTIONS
__attribute__((noreturn))
static void demangling_terminate_handler()
{
- abort_message("terminating");
+ __abort_message("terminating");
}
#endif // !_LIBCXXABI_NO_EXCEPTIONS
lib/libcxxabi/src/cxa_demangle.cpp
@@ -28,10 +28,6 @@
using namespace itanium_demangle;
-constexpr const char *itanium_demangle::FloatData<float>::spec;
-constexpr const char *itanium_demangle::FloatData<double>::spec;
-constexpr const char *itanium_demangle::FloatData<long double>::spec;
-
// <discriminator> := _ <non-negative number> # when number < 10
// := __ <non-negative number> _ # when number >= 10
// extension := decimal-digit+ # at the end of string
lib/libcxxabi/src/cxa_exception_storage.cpp
@@ -56,17 +56,17 @@ extern "C" {
namespace __cxxabiv1 {
namespace {
std::__libcpp_tls_key key_;
- std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;
+ constinit std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;
void _LIBCPP_TLS_DESTRUCTOR_CC destruct_(void *p) {
__free_with_fallback(p);
if (0 != std::__libcpp_tls_set(key_, NULL))
- abort_message("cannot zero out thread value for __cxa_get_globals()");
+ __abort_message("cannot zero out thread value for __cxa_get_globals()");
}
void construct_() {
if (0 != std::__libcpp_tls_create(&key_, destruct_))
- abort_message("cannot create thread specific key for __cxa_get_globals()");
+ __abort_message("cannot create thread specific key for __cxa_get_globals()");
}
} // namespace
@@ -80,9 +80,9 @@ extern "C" {
retVal = static_cast<__cxa_eh_globals*>(
__calloc_with_fallback(1, sizeof(__cxa_eh_globals)));
if (NULL == retVal)
- abort_message("cannot allocate __cxa_eh_globals");
+ __abort_message("cannot allocate __cxa_eh_globals");
if (0 != std::__libcpp_tls_set(key_, retVal))
- abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
+ __abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
}
return retVal;
}
@@ -94,7 +94,7 @@ extern "C" {
__cxa_eh_globals *__cxa_get_globals_fast() {
// First time through, create the key.
if (0 != std::__libcpp_execute_once(&flag_, construct_))
- abort_message("execute once failure in __cxa_get_globals_fast()");
+ __abort_message("execute once failure in __cxa_get_globals_fast()");
return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
}
} // extern "C"
lib/libcxxabi/src/cxa_guard_impl.h
@@ -91,7 +91,7 @@
// the former.
#ifdef BUILDING_CXA_GUARD
# include "abort_message.h"
-# define ABORT_WITH_MESSAGE(...) ::abort_message(__VA_ARGS__)
+# define ABORT_WITH_MESSAGE(...) ::__abort_message(__VA_ARGS__)
#elif defined(TESTING_CXA_GUARD)
# define ABORT_WITH_MESSAGE(...) ::abort()
#else
@@ -156,12 +156,12 @@ private:
// PlatformGetThreadID
//===----------------------------------------------------------------------===//
-#if defined(__APPLE__) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+#if defined(__APPLE__) && _LIBCPP_HAS_THREAD_API_PTHREAD
uint32_t PlatformThreadID() {
static_assert(sizeof(mach_port_t) == sizeof(uint32_t), "");
return static_cast<uint32_t>(pthread_mach_thread_np(std::__libcpp_thread_get_current_id()));
}
-#elif defined(SYS_gettid) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+#elif defined(SYS_gettid) && _LIBCPP_HAS_THREAD_API_PTHREAD
uint32_t PlatformThreadID() {
static_assert(sizeof(pid_t) == sizeof(uint32_t), "");
return static_cast<uint32_t>(syscall(SYS_gettid));
@@ -676,8 +676,8 @@ static_assert(CurrentImplementation != Implementation::Futex || PlatformSupports
using SelectedImplementation = SelectImplementation<CurrentImplementation>::type;
-} // end namespace
-} // end namespace __cxxabiv1
+} // namespace
+} // namespace __cxxabiv1
#if defined(__clang__)
# pragma clang diagnostic pop
lib/libcxxabi/src/cxa_handlers.cpp
@@ -33,7 +33,7 @@ __unexpected(unexpected_handler func)
{
func();
// unexpected handler should not return
- abort_message("unexpected_handler unexpectedly returned");
+ __abort_message("unexpected_handler unexpectedly returned");
}
__attribute__((noreturn))
@@ -58,13 +58,13 @@ __terminate(terminate_handler func) noexcept
#endif // _LIBCXXABI_NO_EXCEPTIONS
func();
// handler should not return
- abort_message("terminate_handler unexpectedly returned");
+ __abort_message("terminate_handler unexpectedly returned");
#ifndef _LIBCXXABI_NO_EXCEPTIONS
}
catch (...)
{
// handler should not throw exception
- abort_message("terminate_handler unexpectedly threw an exception");
+ __abort_message("terminate_handler unexpectedly threw an exception");
}
#endif // _LIBCXXABI_NO_EXCEPTIONS
}
lib/libcxxabi/src/cxa_personality.cpp
@@ -167,7 +167,7 @@ uintptr_t readPointerHelper(const uint8_t*& p) {
return static_cast<uintptr_t>(value);
}
-} // end namespace
+} // namespace
extern "C"
{
lib/libcxxabi/src/cxa_thread_atexit.cpp
@@ -89,7 +89,7 @@ namespace {
// __cxa_thread_atexit() may be called arbitrarily late (for example, from
// global destructors or atexit() handlers).
if (std::__libcpp_tls_create(&dtors_key, run_dtors) != 0) {
- abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()");
+ __abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()");
}
}
lib/libcxxabi/src/cxa_vector.cpp
@@ -121,7 +121,7 @@ void throw_bad_array_new_length() {
#ifndef _LIBCXXABI_NO_EXCEPTIONS
throw std::bad_array_new_length();
#else
- abort_message("__cxa_vec_new failed to allocate memory");
+ __abort_message("__cxa_vec_new failed to allocate memory");
#endif
}
lib/libcxxabi/src/cxa_virtual.cpp
@@ -13,12 +13,12 @@ namespace __cxxabiv1 {
extern "C" {
_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN
void __cxa_pure_virtual(void) {
- abort_message("Pure virtual function called!");
+ __abort_message("Pure virtual function called!");
}
_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN
void __cxa_deleted_virtual(void) {
- abort_message("Deleted virtual function called!");
+ __abort_message("Deleted virtual function called!");
}
} // extern "C"
} // abi
lib/libcxxabi/src/fallback_malloc.cpp
@@ -259,7 +259,7 @@ void* __aligned_malloc_with_fallback(size_t size) {
#if defined(_WIN32)
if (void* dest = std::__libcpp_aligned_alloc(alignof(__aligned_type), size))
return dest;
-#elif defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
+#elif !_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
if (void* dest = ::malloc(size))
return dest;
#else
@@ -286,7 +286,7 @@ void __aligned_free_with_fallback(void* ptr) {
if (is_fallback_ptr(ptr))
fallback_free(ptr);
else {
-#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
+#if !_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
::free(ptr);
#else
std::__libcpp_aligned_free(ptr);
lib/libcxxabi/src/private_typeinfo.cpp
@@ -41,9 +41,11 @@
// Defining _LIBCXXABI_FORGIVING_DYNAMIC_CAST does not help since can_catch() calls
// is_equal() with use_strcmp=false so the string names are not compared.
-#include <cstdint>
#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <string.h>
+
#include "abort_message.h"
#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
@@ -589,10 +591,9 @@ __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
// .. and reset the pointer.
adjustedPtr = nullptr;
}
- __base_type->has_unambiguous_public_base(
- info,
- static_cast<char*>(adjustedPtr) + offset_to_base,
- (__offset_flags & __public_mask) ? path_below : not_public_path);
+ __base_type->has_unambiguous_public_base(
+ info, reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(adjustedPtr) + offset_to_base),
+ (__offset_flags & __public_mask) ? path_below : not_public_path);
}
void
lib/libcxxabi/src/stdlib_new_delete.cpp
@@ -24,22 +24,22 @@
# error The _LIBCPP_WEAK macro should be already defined by libc++
#endif
-#if defined(_LIBCXXABI_NO_EXCEPTIONS) != defined(_LIBCPP_HAS_NO_EXCEPTIONS)
+#if defined(_LIBCXXABI_NO_EXCEPTIONS) != !_LIBCPP_HAS_EXCEPTIONS
# error libc++ and libc++abi seem to disagree on whether exceptions are enabled
#endif
inline void __throw_bad_alloc_shim() {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
throw std::bad_alloc();
#else
- abort_message("bad_alloc was thrown in -fno-exceptions mode");
+ __abort_message("bad_alloc was thrown in -fno-exceptions mode");
#endif
}
#define _LIBCPP_ASSERT_SHIM(expr, str) \
do { \
if (!expr) \
- abort_message(str); \
+ __abort_message(str); \
} while (false)
// ------------------ BEGIN COPY ------------------
@@ -71,7 +71,7 @@ _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std
}
_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
-#ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+#if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),
@@ -99,7 +99,7 @@ _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](s
}
_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
-#ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+#if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),
@@ -134,7 +134,7 @@ _LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept {
_LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
-#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
+#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) {
if (size == 0)
@@ -165,7 +165,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
}
_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
-# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),
@@ -194,7 +194,7 @@ operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
}
_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
-# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),
@@ -240,5 +240,5 @@ _LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignmen
::operator delete[](ptr, alignment);
}
-#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+#endif // _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
// ------------------ END COPY ------------------