diff --git a/packages/cxx-frontend/src/TokenKind.ts b/packages/cxx-frontend/src/TokenKind.ts index eab426a6..5da53f8d 100644 --- a/packages/cxx-frontend/src/TokenKind.ts +++ b/packages/cxx-frontend/src/TokenKind.ts @@ -108,10 +108,12 @@ export enum TokenKind { __FLOAT80, __IMAG__, __INT128, + __INT128_T, __INT64, __REAL__, __RESTRICT__, __THREAD, + __UINT128_T, __UNDERLYING_TYPE, ALIGNAS, ALIGNOF, diff --git a/packages/cxx-gen-ast/src/tokens.ts b/packages/cxx-gen-ast/src/tokens.ts index 94e334d0..b026e8a3 100644 --- a/packages/cxx-gen-ast/src/tokens.ts +++ b/packages/cxx-gen-ast/src/tokens.ts @@ -176,6 +176,7 @@ export const CXX_KEYWORDS: string[] = [ "volatile", "wchar_t", "while", + "__attribute__", "__builtin_bit_cast", "__builtin_offsetof", @@ -186,11 +187,13 @@ export const CXX_KEYWORDS: string[] = [ "__float128", "__float80", "__imag__", + "__int128_t", "__int128", "__int64", "__real__", "__restrict__", "__thread", + "__uint128_t", "__underlying_type", "_Atomic", "_Complex", @@ -344,12 +347,13 @@ export const C_KEYWORDS: string[] = [ "__float128", "__float80", "__imag__", + "__int128_t", "__int128", "__int64", "__real__", "__thread", + "__uint128_t", "__underlying_type", - "_Atomic", "_Complex", ]; diff --git a/src/lib/cxx/include/stddef.h b/src/lib/cxx/include/stddef.h index 4e07d5bd..62a9dcea 100644 --- a/src/lib/cxx/include/stddef.h +++ b/src/lib/cxx/include/stddef.h @@ -1,36 +1,76 @@ -#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \ - !defined(__need_wchar_t) && !defined(__need_NULL) && \ - !defined(__need_STDDEF_H_misc) +#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \ + !defined(__need_wchar_t) && !defined(__need_NULL) && \ + !defined(__need_rsize_t) && !defined(__need_nullptr_t) && \ + !defined(__need_max_align_t) && !defined(__need_offsetof) && \ + !defined(__need_wint_t) #define __need_ptrdiff_t #define __need_size_t #define __need_wchar_t +#define __need_offsetof +#define __need_max_align_t + +#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 +#define __need_rsize_t +#endif + +#if !defined(__STDDEF_H) #define __need_NULL -#define __need_STDDEF_H_misc #endif +#endif /* no needs */ + #ifdef __need_ptrdiff_t #undef __need_ptrdiff_t -typedef long int ptrdiff_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; #endif /* __need_ptrdiff_t */ #ifdef __need_size_t #undef __need_size_t -typedef long unsigned int size_t; +typedef __SIZE_TYPE__ size_t; #endif /* __need_size_t */ +#ifdef __need_rsize_t +#undef __need_rsize_t +typedef __SIZE_TYPE__ rsize_t; +#endif /* __need_size_t */ + +#ifdef __need_ptrdiff_t +#undef __need_ptrdiff_t +typedef __PTRDIFF_TYPE__ ptrdiff_t; +#endif /* __need_ptrdiff_t */ + #ifdef __need_wchar_t #undef __need_wchar_t +#ifndef __cplusplus +#if !defined(_WCHAR_T) +#define _WCHAR_T +typedef __WCHAR_TYPE__ wchar_t; +#endif /* _WCHAR_T */ +#endif /* __cplusplus */ #endif /* __need_wchar_t */ #ifdef __need_NULL #undef __need_NULL -#undef NULL +#if !defined(NULL) #define NULL 0 +#endif /* NULL */ #endif /* __need_NULL */ -#ifdef __need_STDDEF_H_misc -#undef __need_STDDEF_H_misc -typedef long unsigned int rsize_t; +#ifdef __need_wint_t +#undef __need_wint_t +typedef __WINT_TYPE__ wint_t; +#endif /* __need_wint_t */ + +#ifdef __need_offsetof +#undef __need_offsetof +#if !defined(offsetof) +#define offsetof(t, d) __builtin_offsetof(t, d) +#endif + +#endif /* __need_offsetof */ + +#ifdef __need_max_align_t +#undef __need_max_align_t typedef struct { long long __clang_max_align_nonce1 @@ -40,19 +80,4 @@ typedef struct { __attribute__((__aligned__(__alignof__(long double)))); } max_align_t; -#endif /* __need_STDDEF_H_misc */ - -#ifdef __need_wint_t -#undef __need_wint_t - -#ifdef __WINT_TYPE__ -typedef __WINT_TYPE__ wint_t; -#else -typedef int wint_t; -#endif - -#endif /* __need_wint_t */ - -#if !defined(offsetof) -#define offsetof(t, d) __builtin_offsetof(t, d) -#endif +#endif /* __need_max_align_t */ diff --git a/src/parser/cxx/control.cc b/src/parser/cxx/control.cc index d980e335..98eafd89 100644 --- a/src/parser/cxx/control.cc +++ b/src/parser/cxx/control.cc @@ -90,11 +90,13 @@ struct Control::Private { IntType intType; LongIntType longIntType; LongLongIntType longLongIntType; + Int128Type int128Type; UnsignedCharType unsignedCharType; UnsignedShortIntType unsignedShortIntType; UnsignedIntType unsignedIntType; UnsignedLongIntType unsignedLongIntType; UnsignedLongLongIntType unsignedLongLongIntType; + UnsignedInt128Type unsignedInt128Type; CharType charType; Char8Type char8Type; Char16Type char16Type; @@ -302,6 +304,8 @@ auto Control::getLongLongIntType() -> const LongLongIntType* { return &d->longLongIntType; } +auto Control::getInt128Type() -> const Int128Type* { return &d->int128Type; } + auto Control::getUnsignedCharType() -> const UnsignedCharType* { return &d->unsignedCharType; } @@ -322,6 +326,10 @@ auto Control::getUnsignedLongLongIntType() -> const UnsignedLongLongIntType* { return &d->unsignedLongLongIntType; } +auto Control::getUnsignedInt128Type() -> const UnsignedInt128Type* { + return &d->unsignedInt128Type; +} + auto Control::getCharType() -> const CharType* { return &d->charType; } auto Control::getChar8Type() -> const Char8Type* { return &d->char8Type; } diff --git a/src/parser/cxx/control.h b/src/parser/cxx/control.h index a9466bd6..1cc1f58f 100644 --- a/src/parser/cxx/control.h +++ b/src/parser/cxx/control.h @@ -88,12 +88,14 @@ class Control { [[nodiscard]] auto getIntType() -> const IntType*; [[nodiscard]] auto getLongIntType() -> const LongIntType*; [[nodiscard]] auto getLongLongIntType() -> const LongLongIntType*; + [[nodiscard]] auto getInt128Type() -> const Int128Type*; [[nodiscard]] auto getUnsignedCharType() -> const UnsignedCharType*; [[nodiscard]] auto getUnsignedShortIntType() -> const UnsignedShortIntType*; [[nodiscard]] auto getUnsignedIntType() -> const UnsignedIntType*; [[nodiscard]] auto getUnsignedLongIntType() -> const UnsignedLongIntType*; [[nodiscard]] auto getUnsignedLongLongIntType() -> const UnsignedLongLongIntType*; + [[nodiscard]] auto getUnsignedInt128Type() -> const UnsignedInt128Type*; [[nodiscard]] auto getCharType() -> const CharType*; [[nodiscard]] auto getChar8Type() -> const Char8Type*; [[nodiscard]] auto getChar16Type() -> const Char16Type*; diff --git a/src/parser/cxx/decl_specs.cc b/src/parser/cxx/decl_specs.cc index 2d909f1e..b91e48d5 100644 --- a/src/parser/cxx/decl_specs.cc +++ b/src/parser/cxx/decl_specs.cc @@ -222,8 +222,13 @@ void DeclSpecs::Visitor::operator()(IntegralTypeSpecifierAST* ast) { // ### todo break; + case TokenKind::T___INT128_T: case TokenKind::T___INT128: - // ### todo + specs.type_ = control()->getInt128Type(); + break; + + case TokenKind::T___UINT128_T: + specs.type_ = control()->getUnsignedInt128Type(); break; default: @@ -401,6 +406,10 @@ void DeclSpecs::finish() { type_ = control()->getIntType(); } + if (type_ == control()->getInt128Type() && isUnsigned) { + type_ = control()->getUnsignedInt128Type(); + } + if (!type_) { return; } diff --git a/src/parser/cxx/external_name_encoder.cc b/src/parser/cxx/external_name_encoder.cc index f477e5eb..a60994e7 100644 --- a/src/parser/cxx/external_name_encoder.cc +++ b/src/parser/cxx/external_name_encoder.cc @@ -66,6 +66,8 @@ struct ExternalNameEncoder::TypeVisitor { void operator()(const LongLongIntType* type) { encoder.out("x"); } + void operator()(const Int128Type* type) { encoder.out("n"); } + void operator()(const UnsignedCharType* type) { encoder.out("h"); } void operator()(const UnsignedShortIntType* type) { encoder.out("t"); } @@ -76,6 +78,8 @@ struct ExternalNameEncoder::TypeVisitor { void operator()(const UnsignedLongLongIntType* type) { encoder.out("y"); } + void operator()(const UnsignedInt128Type* type) { encoder.out("o"); } + void operator()(const CharType* type) { encoder.out("c"); } void operator()(const Char8Type* type) { encoder.out("Du"); } diff --git a/src/parser/cxx/memory_layout.cc b/src/parser/cxx/memory_layout.cc index 92746dfd..d27916fd 100644 --- a/src/parser/cxx/memory_layout.cc +++ b/src/parser/cxx/memory_layout.cc @@ -80,6 +80,10 @@ struct SizeOf { return memoryLayout.sizeOfLongLong(); } + auto operator()(const Int128Type*) const -> std::optional { + return 16; + } + auto operator()(const UnsignedCharType* type) const -> std::optional { return 1; @@ -105,6 +109,11 @@ struct SizeOf { return memoryLayout.sizeOfLongLong(); } + auto operator()(const UnsignedInt128Type*) const + -> std::optional { + return 16; + } + auto operator()(const CharType* type) const -> std::optional { return 1; } diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index c7ba3288..9acbf33a 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -5046,6 +5046,8 @@ auto Parser::parse_primitive_type_specifier(SpecifierAST*& yyast, case TokenKind::T_INT: case TokenKind::T___INT64: case TokenKind::T___INT128: + case TokenKind::T___INT128_T: + case TokenKind::T___UINT128_T: makeIntegralTypeSpecifier(); specs.accept(yyast); return true; diff --git a/src/parser/cxx/private/c_keywords-priv.h b/src/parser/cxx/private/c_keywords-priv.h index e3ccd78e..86bba309 100644 --- a/src/parser/cxx/private/c_keywords-priv.h +++ b/src/parser/cxx/private/c_keywords-priv.h @@ -785,25 +785,21 @@ static inline auto classifyC10(const char* s) -> cxx::TokenKind { } } } - } else if (s[2] == 'd') { - if (s[3] == 'e') { - if (s[4] == 'c') { - if (s[5] == 'l') { - if (s[6] == 't') { - if (s[7] == 'y') { - if (s[8] == 'p') { - if (s[9] == 'e') { - return cxx::TokenKind::T___DECLTYPE; + } else if (s[2] == 'i') { + if (s[3] == 'n') { + if (s[4] == 't') { + if (s[5] == '1') { + if (s[6] == '2') { + if (s[7] == '8') { + if (s[8] == '_') { + if (s[9] == 't') { + return cxx::TokenKind::T___INT128_T; } } } } } - } - } - } else if (s[2] == 'i') { - if (s[3] == 'n') { - if (s[4] == 'l') { + } else if (s[4] == 'l') { if (s[5] == 'i') { if (s[6] == 'n') { if (s[7] == 'e') { @@ -817,6 +813,22 @@ static inline auto classifyC10(const char* s) -> cxx::TokenKind { } } } + } else if (s[2] == 'd') { + if (s[3] == 'e') { + if (s[4] == 'c') { + if (s[5] == 'l') { + if (s[6] == 't') { + if (s[7] == 'y') { + if (s[8] == 'p') { + if (s[9] == 'e') { + return cxx::TokenKind::T___DECLTYPE; + } + } + } + } + } + } + } } else if (s[2] == 'r') { if (s[3] == 'e') { if (s[4] == 's') { @@ -912,6 +924,24 @@ static inline auto classifyC11(const char* s) -> cxx::TokenKind { } } } + } else if (s[2] == 'u') { + if (s[3] == 'i') { + if (s[4] == 'n') { + if (s[5] == 't') { + if (s[6] == '1') { + if (s[7] == '2') { + if (s[8] == '8') { + if (s[9] == '_') { + if (s[10] == 't') { + return cxx::TokenKind::T___UINT128_T; + } + } + } + } + } + } + } + } } else if (s[2] == 'a') { if (s[3] == 'l') { if (s[4] == 'i') { diff --git a/src/parser/cxx/private/keywords-priv.h b/src/parser/cxx/private/keywords-priv.h index 11c831fc..36c975e8 100644 --- a/src/parser/cxx/private/keywords-priv.h +++ b/src/parser/cxx/private/keywords-priv.h @@ -1159,25 +1159,21 @@ static inline auto classify10(const char* s) -> cxx::TokenKind { } } } - } else if (s[2] == 'd') { - if (s[3] == 'e') { - if (s[4] == 'c') { - if (s[5] == 'l') { - if (s[6] == 't') { - if (s[7] == 'y') { - if (s[8] == 'p') { - if (s[9] == 'e') { - return cxx::TokenKind::T___DECLTYPE; + } else if (s[2] == 'i') { + if (s[3] == 'n') { + if (s[4] == 't') { + if (s[5] == '1') { + if (s[6] == '2') { + if (s[7] == '8') { + if (s[8] == '_') { + if (s[9] == 't') { + return cxx::TokenKind::T___INT128_T; } } } } } - } - } - } else if (s[2] == 'i') { - if (s[3] == 'n') { - if (s[4] == 'l') { + } else if (s[4] == 'l') { if (s[5] == 'i') { if (s[6] == 'n') { if (s[7] == 'e') { @@ -1191,6 +1187,22 @@ static inline auto classify10(const char* s) -> cxx::TokenKind { } } } + } else if (s[2] == 'd') { + if (s[3] == 'e') { + if (s[4] == 'c') { + if (s[5] == 'l') { + if (s[6] == 't') { + if (s[7] == 'y') { + if (s[8] == 'p') { + if (s[9] == 'e') { + return cxx::TokenKind::T___DECLTYPE; + } + } + } + } + } + } + } } else if (s[2] == 'r') { if (s[3] == 'e') { if (s[4] == 's') { @@ -1288,6 +1300,24 @@ static inline auto classify11(const char* s) -> cxx::TokenKind { } } } + } else if (s[2] == 'u') { + if (s[3] == 'i') { + if (s[4] == 'n') { + if (s[5] == 't') { + if (s[6] == '1') { + if (s[7] == '2') { + if (s[8] == '8') { + if (s[9] == '_') { + if (s[10] == 't') { + return cxx::TokenKind::T___UINT128_T; + } + } + } + } + } + } + } + } } else if (s[2] == 'a') { if (s[3] == 'l') { if (s[4] == 'i') { diff --git a/src/parser/cxx/symbol_instantiation.cc b/src/parser/cxx/symbol_instantiation.cc index c97168ce..a3005461 100644 --- a/src/parser/cxx/symbol_instantiation.cc +++ b/src/parser/cxx/symbol_instantiation.cc @@ -97,6 +97,7 @@ struct SymbolInstantiation::VisitType { [[nodiscard]] auto operator()(const IntType* type) -> const Type*; [[nodiscard]] auto operator()(const LongIntType* type) -> const Type*; [[nodiscard]] auto operator()(const LongLongIntType* type) -> const Type*; + [[nodiscard]] auto operator()(const Int128Type* type) -> const Type*; [[nodiscard]] auto operator()(const UnsignedCharType* type) -> const Type*; [[nodiscard]] auto operator()(const UnsignedShortIntType* type) -> const Type*; @@ -104,6 +105,7 @@ struct SymbolInstantiation::VisitType { [[nodiscard]] auto operator()(const UnsignedLongIntType* type) -> const Type*; [[nodiscard]] auto operator()(const UnsignedLongLongIntType* type) -> const Type*; + [[nodiscard]] auto operator()(const UnsignedInt128Type* type) -> const Type*; [[nodiscard]] auto operator()(const CharType* type) -> const Type*; [[nodiscard]] auto operator()(const Char8Type* type) -> const Type*; [[nodiscard]] auto operator()(const Char16Type* type) -> const Type*; @@ -465,6 +467,11 @@ auto SymbolInstantiation::VisitType::operator()(const LongLongIntType* type) return type; } +auto SymbolInstantiation::VisitType::operator()(const Int128Type* type) + -> const Type* { + return type; +} + auto SymbolInstantiation::VisitType::operator()(const UnsignedCharType* type) -> const Type* { return type; @@ -485,6 +492,11 @@ auto SymbolInstantiation::VisitType::operator()(const UnsignedLongIntType* type) return type; } +auto SymbolInstantiation::VisitType::operator()(const UnsignedInt128Type* type) + -> const Type* { + return type; +} + auto SymbolInstantiation::VisitType::operator()( const UnsignedLongLongIntType* type) -> const Type* { return type; diff --git a/src/parser/cxx/token_fwd.h b/src/parser/cxx/token_fwd.h index 3d9b2061..0cd90209 100644 --- a/src/parser/cxx/token_fwd.h +++ b/src/parser/cxx/token_fwd.h @@ -123,10 +123,12 @@ class Token; V(__FLOAT80, "__float80") \ V(__IMAG__, "__imag__") \ V(__INT128, "__int128") \ + V(__INT128_T, "__int128_t") \ V(__INT64, "__int64") \ V(__REAL__, "__real__") \ V(__RESTRICT__, "__restrict__") \ V(__THREAD, "__thread") \ + V(__UINT128_T, "__uint128_t") \ V(__UNDERLYING_TYPE, "__underlying_type") \ V(ALIGNAS, "alignas") \ V(ALIGNOF, "alignof") \ diff --git a/src/parser/cxx/type_printer.cc b/src/parser/cxx/type_printer.cc index 0f95de22..da1d319e 100644 --- a/src/parser/cxx/type_printer.cc +++ b/src/parser/cxx/type_printer.cc @@ -132,6 +132,12 @@ class TypePrinter { specifiers_.append("unsigned long long"); } + void operator()(const Int128Type* type) { specifiers_.append("__int128_t"); } + + void operator()(const UnsignedInt128Type* type) { + specifiers_.append("__uint128_t"); + } + void operator()(const FloatType* type) { specifiers_.append("float"); } void operator()(const DoubleType* type) { specifiers_.append("double"); } diff --git a/src/parser/cxx/type_traits.h b/src/parser/cxx/type_traits.h index 000e89c1..6dccc613 100644 --- a/src/parser/cxx/type_traits.h +++ b/src/parser/cxx/type_traits.h @@ -864,6 +864,10 @@ class TypeTraits { return true; } + auto operator()(const Int128Type*, const Int128Type*) const -> bool { + return true; + } + auto operator()(const UnsignedCharType*, const UnsignedCharType*) const -> bool { return true; @@ -889,6 +893,11 @@ class TypeTraits { return true; } + auto operator()(const UnsignedInt128Type*, const UnsignedInt128Type*) const + -> bool { + return true; + } + auto operator()(const CharType*, const CharType*) const -> bool { return true; } diff --git a/src/parser/cxx/types.h b/src/parser/cxx/types.h index 1d0e0e96..c17cfcec 100644 --- a/src/parser/cxx/types.h +++ b/src/parser/cxx/types.h @@ -107,6 +107,12 @@ class LongLongIntType final : public Type { LongLongIntType() : Type(Kind) {} }; +class Int128Type final : public Type { + public: + static constexpr TypeKind Kind = TypeKind::kInt128; + Int128Type() : Type(Kind) {} +}; + class UnsignedCharType final : public Type { public: static constexpr TypeKind Kind = TypeKind::kUnsignedChar; @@ -137,6 +143,12 @@ class UnsignedLongLongIntType final : public Type { UnsignedLongLongIntType() : Type(Kind) {} }; +class UnsignedInt128Type final : public Type { + public: + static constexpr TypeKind Kind = TypeKind::kUnsignedInt128; + UnsignedInt128Type() : Type(Kind) {} +}; + class CharType final : public Type { public: static constexpr TypeKind Kind = TypeKind::kChar; diff --git a/src/parser/cxx/types_fwd.h b/src/parser/cxx/types_fwd.h index 7edd5f13..86c246d2 100644 --- a/src/parser/cxx/types_fwd.h +++ b/src/parser/cxx/types_fwd.h @@ -40,11 +40,13 @@ class Name; V(Int) \ V(LongInt) \ V(LongLongInt) \ + V(Int128) \ V(UnsignedChar) \ V(UnsignedShortInt) \ V(UnsignedInt) \ V(UnsignedLongInt) \ V(UnsignedLongLongInt) \ + V(UnsignedInt128) \ V(Char) \ V(Char8) \ V(Char16) \ diff --git a/tests/unit_tests/parser/c_stdlib.c b/tests/unit_tests/parser/c_stdlib.c index 19fbe8bd..25eb271a 100644 --- a/tests/unit_tests/parser/c_stdlib.c +++ b/tests/unit_tests/parser/c_stdlib.c @@ -1,4 +1,4 @@ -// RUN: %cxx -toolchain wasm32 -verify %s +// RUN: %cxx -toolchain wasm32 -verify -fcheck %s #include #include