Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Algol68
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C with Coccinelle
C++ with Coccinelle
C++ (Circle)
CIRCT
Clean
Clojure
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
GLSL
Go
Haskell
HLSL
Helion
Hook
Hylo
IL
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Mojo
Nim
Numba
Nix
Objective-C
Objective-C++
OCaml
Odin
OpenCL C
Pascal
Pony
PTX
Python
Racket
Raku
Ruby
Rust
Sail
Snowball
Scala
Slang
Solidity
Spice
SPIR-V
Swift
LLVM TableGen
Toit
Triton
TypeScript Native
V
Vala
Visual Basic
Vyper
WASM
Yul (Solidity IR)
Zig
Javascript
GIMPLE
Ygen
sway
cpp2_cppfront source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
cppfront trunk
Options
Source code
// Clang Format test cases. // Cpp1 and Cpp2 next to each other // to show degree of consistent formatting. int x = 0; const int x = 0; const int* x = 0; int* const x = 0; const int* const x = 0; x: i32 = 0; x: const i32 = 0; x: * const i32 = 0; x: const * i32 = 0; x: const * const i32 = 0; auto x = 0; x: _ = 0; x := 0; void f() { } f: () = { } void f() { int x = 0; } f: () = { x: i32 = 0; } int f() { return 0; } f: () -> i32 = { return 0; } f: () -> i32 = 0; auto f(const auto& x) { return x; } f: (in x: _) -> _ = { return x; } f: (x) -> _ = x; void f(const int) { } void f(const int x) { } f: (:i32) = { } // Pending [grammar][]. f: (x: i32) = { } void f(int) { } f: (copy: i32) = { } // Pending [grammar][]. void f(buffer& x) { } f: (inout x: buffer) = { } f: (out x: buffer) = { } int&& f(int&&); f: (move: i32) -> move i32; // Pending [grammar][]. auto&& f(uncvref_same<int>&& x) { return FWD(x); } f: (forward x: i32) -> forward _ = forward x; // Pending [hsutter/cppfront#408][]. void f() { g(); g(); } f: () = { g(); g(); } class t { }; class t final { }; t: type = { } t: final type = { } class t { int x = 0; }; t: type = { x: i32 = 0; } class t : base { t() : base{""} { } }; t: type = { this: base = ""; } class t { private: void f() const { } }; t: type = { private f: (this) = { } } class t { private: void f() const { } private: void f() const { } }; t: type = { private f: (this) = { } private f: (this) = { } } class t { void f() const { g(); } }; t: type = { f: (this) = g(); f: (this) = { g(); } } class t { static void f() { g(); g(); } }; t: type = { f: () = { g(); g(); } } class t { [[nodiscard]] bool operator==(const t&) const = default; }; t: type = { operator==: (this, that) -> bool; } class t { virtual ~t() { } virtual void f() const = 0; }; t: type = { operator=: (virtual move this) = { } f: (virtual this); } t: @interface type = { f: (this); } class t { int x = 0; [[nodiscard]] int get() const { return x; } void set(const int y) { x = y; } }; t: type = { x: i32 = 0; get: (this) -> i32 = x; set: (inout this, y: i32) = x = y; } namespace ns { } ns: namespace = { } namespace ns { int x = 0; } // namespace ns ns: namespace = { x: i32 = 0; } // namespace ns namespace ns { int x = 0; void f() { } } // namespace ns ns: namespace = { x: i32 = 0; f: () = { } } // namespace ns namespace a { namespace b { int x = 0; } // namespace b } // namespace a a: namespace = { b: namespace = { x: i32 = 0; } // namespace b } // namespace a using t = int; namespace ns = a::b; const auto& x = y; t: type == i32; ns: namespace == a::b; x :== y; void f() { [] {}; } f: () = { :() = {}; } void f() { [] {}(); [] { return 0; }(); [] { g(); }(); } f: () = { :() = {}(); :() -> _ = { return 0; }(); :() -> _ = 0;(); :() = { g(); }(); :() = g();(); } void f() { [] { g(); g() }; [] { g(); g() }(); } f: () = { :() = { g(); g(); }; :() = { g(); g(); }(); } void f() { [] { [] {}; }; [] {}([] {}); } f: () = { :() = { :() = {}; }; :() = {}(:() = {}); } f: () = :() = { :() = {}; }; f: () = :() = {}(:() = {}); f: () = { // _primary-expression_. (:() = 0); (:() = 0;); (:() = 0;()); :int = 0; // _postfix-expression_. :int = 0;(); :() = 0;(); g(:() = 0); g(:() = 0;); g(:() = 0;()); g(:() = 0, a); g(:() = 0;, a); g(:() = 0;(), a); x[:() = 0]; x[:() = 0;]; x[:() = 0;()]; x[:() = 0, a]; x[:() = 0;, a]; x[:() = 0;(), a]; x*; x&; x~; x$; x*&~$; x$~&*; // _prefix-expression_. move x; // Pending [hsutter/cppfront#408][]. +move x; // Pending [hsutter/cppfront#408][]. // _is-as-expression_. x is t; x is 0; x as t; is is * (); // Pending [grammar][]. is is is; (is) is (is); (is) is (is)&; (is) is (is&); is* is (); // Pending [grammar][]. is as is; is as * (); // Pending [grammar][]. (is) as * (); // Pending [grammar][]. :() = 0; as t; :() = 0; is t; x is :() = 0; x is :() = 0;(); // Chained comparisons. min <= x < max; a == b == c; } void f() { if (a || b) g(); if (a || b) { g(); } } f: () = { if (a || b) { g(); } if a || b { g(); } (x := 0) if a || b { g(); } } void f() { if (a || b) g(); else x = 0; if (a || b) { g(); } else { x = 0; } } f: () = { if (a || b) { g(); } else { x = 0; } if a || b { g(); } else { x = 0; } (x := 0) if a || b { g(); } else { x = 0; } } void f() { if (a || b) g(); else if (true) x = 0; else x = 1; if (a || b) { g(); } else if (true) { x = 0; } else { x = 1; } } f: () = { if (a || b) { g(); } else if (true) { x = 0; } else { x = 1; } if a || b { g(); } else if true { x = 0; } else { x = 1; } } void f() { if constexpr (a || b) g(); else if constexpr (true) x = 0; else x = 1; if constexpr (a || b) { g(); } else if constexpr (true) { x = 0; } else { x = 1; } } f: () = { if constexpr (a || b) { g(); } else if constexpr (true) { x = 0; } else { x = 1; } if constexpr a || b { g(); } else if constexpr true { x = 0; } else { x = 1; } } f: () = { inspect x { is _ = g(); } (x := 0) inspect x { is _ = g(); } inspect constexpr x { y: is _ = g(); } inspect x { is t = g(); is _ = g(); } (x := 0) inspect x { is t = g(); is _ = g(); } inspect x { is t = { g(); g(); } is _ = g(); } (inspect x -> i32 { is _ = 0; }); (inspect x -> i32 { is i32 = 0; is _ = 1; }); std::cout << inspect x -> i32 { is _ = 0; } << '\n'; std::cout << inspect x -> i32 { is i32 = 0; is _ = 1; } << '\n'; } f: () = { return (move x); return move x; // Pending [hsutter/cppfront#408][]. return :int = 0; return :() = 0;(); return x&; (x := 0) return x&; break; break pre; continue; continue pre; (x := 0) continue pre; } void f() { while (a || b) g(); while (a || b) { g(); } } f: () = { while (a || b) { g(); } while a || b { g(); } (x := 0) while a || b { g(); } } void f() { while (a || b) { g(); g(); } } f: () = { while (a || b) { g(); g(); } while a || b { g(); g(); } } void f() { while (a || b) { g(); ++x; } } f: () = { while (a || b) next x++ { g(); } while a || b next x++ { g(); } while (a || b) next x++ { g(); g(); } while a || b next x++ { g(); g(); } (x := 0) while a || b next x++ { g(); g(); } } void f() { do { g(); } while (a || b); } f: () = { do { g(); } while (a || b); do { g(); } while a || b; (x := 0) do { g(); } while a || b; } void f() { do { g(); g(); } while (a || b); } f: () = { do { g(); g(); } while (a || b); do { g(); g(); } while a || b; } f: () = { do { g(); } while (a || b) next x++; do { g(); } while a || b next x++; do { g(); g(); } while (a || b) next x++; do { g(); g(); } while a || b next x++; (x := 0) do { g(); g(); } while a || b next x++; } void f() { for (const auto& e : r) g(e); for (const auto& e : r) { g(e); } for (const auto& x = 0; const auto& e : r) { g(e); } } f: () = { for r do (e) g(e); for r do (e) { g(e); } (x := 0) for r do (e) { g(e); } } void f() { for (const auto& e : r) { g(e); ++x; } } f: () = { for r next x++ do (e) g(e); for r next x++ do (e) { g(e); } for r next x++ do (e) { g(e); g(e); } (x := 0) for r next x++ do (e) { g(e); g(e); } } void f() { pre: while (a || b) g(); pre: do { g(); } while (a || b); pre: for (const auto& e : r) g(e); } f: () = { pre: while a || b { g(); } pre: do { g(); } while a || b; pre: for r do (e) g(e); (x := 0) pre: for r do (e) g(e); } void f() { { g(); } { g(); g(); } } f: () = { { g(); } (x := 0) { g(); } { g(); g(); } (x := 0) { g(); g(); } } f: () = { (x := 0) (x := 0) g(); (x := 0) (:() = 0;()); (x := 0) :int = 0;(); (x := 0) :() = { g(); g(); }; (x := 0) g(:() = 0;(), a); (x := 0) x$~&*; (x := 0) move x; // Pending [hsutter/cppfront#408][]. (x := 0) (is) as * (); // Pending [grammar][]. } void f() { [[assume(a || b)]]; } f: () = { [[assert: a || b]] } void f() { [] { [[assume(a || b)]]; }; } f: () = { :() = { [[assert: a || b]] }; } f: () = { [[assert: a || b]] [[assert: a || b]] } f: () = { [[assert: :() -> _ = true;()]] [[assert: :() -> _ = { return true; }()]] } f: () = { [[assert: a || b, "!a && !b"]] } void f() noexcept { } f: () throws = { } void f() requires a { } void f() requires a || b { } void f() requires(a || b) { } f: () requires a = { } f: () requires a || b = { } f: () requires(a || b) = { } void f() requires([] { g(); }()) { } f: () requires :() = { g(); }() = { } f: () requires :() = g();() = { } void f() requires([] { g(); g(); }()) { } f: () requires :() = { g(); g(); }() = { } void f() // requires a || b { g(); } f: () // requires a || b = { g(); } f: () [[pre: true]] = { } f: () [[pre: :() -> _ = {}]] = { } f: () [[pre: :() -> _ = true;()]] = { } f: () [[pre: :() -> _ = { return true; }()]] = { } f: () [[pre: true]] [[post: true]] = { } f: () [[pre: :() = { g(); g(); }()]] = { } f: @meta () = { } f: @meta<T> () = { } f: @meta <T: type> () = { } f: @meta <T, T: type> () = { } f: (x, move y: t) throws -> void = g(); f: <T, V: _> (x, move y: t) throws -> void requires a || b = g(); f: <T, V: _> (x, move y: t) throws -> void [[pre: true]] requires a || b = g(); f: <T, V: _> (x, move y: t) throws -> void [[pre: true]] requires a || b = { g(); } f: @meta <T, V: _> (x, move y: t) throws -> void [[pre: true]] requires a || b = { g(); } f: @meta <T, V: _> (x, move y: t) throws -> void [[pre: true]] requires a || b = { g(); g(); } x := $R"()"; using t = void(); using t = void (*)(); using t = int (*)(); t: type == (); // Pending [grammar][]. t: type == * (); // Pending [grammar][]. t: type == * () -> i32; // Pending [grammar][]. using t = auto (*)() -> auto (*)() -> void; using t = auto (*)() -> auto (*)(int) -> auto (*)() -> int; t: type == * () -> * (); // Pending [grammar][]. t: type == * () -> * (:i32) -> * () -> i32; // Pending [grammar][]. // Adapted from <https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators>. g: () = { // clang-format off f: (:i32) -> * (:i32) -> std::string; // Pending [grammar][]. [[assert: f is (:i32) -> * (:i32) -> std::string]] // Pending [grammar][]. // / | | // / | | [[assert: f(42) is * (:i32) -> std::string]] // Pending [grammar][]. // _______/ | // / | [[assert: f(42)* is (:i32) -> std::string]] // Pending [grammar][]. // ________/ // / [[assert: f(42)*(1) is std::string]] // Pending [grammar][]. } // clang-format on I<8> x; x: I<8>; I<[] {}> x; I<[] {}()> x; x: I<:() = {}>; x: I<:() = {}()>; template<class T> const I<8>* x; template<class T> const I<8>* const x; x: <T> * const I<8>; x: <T> const * const I<8>; template<I<[] {}> V> int x; x: <V: I<:() = {}>> i32; I<[] { return 0; }()> x; x: I<:() -> _ = { return 0; }()>; x: I<:() -> _ = 0;()>; template<I<[] { return 0; }()> V> int x; x: <V: I<:() -> _ = { return 0; }()>> i32; I<8> f(int l, I<8> r); f: (l: i32, r: I<8>) -> I<8>; I<8> (*f)(int l, I<8> r); f: * (l: i32, r: I<8>) -> I<8>; std::tuple<int> f(); f: () -> (a: i32); std::tuple<int, auto (*)(int)->void (*)()> f(); f: () -> std::tuple<i32, * (:i32) -> * ()>; f: () -> (a: i32, b: * (:i32) -> * ()); f := :() = x*$; // f: <T> (x: T<N() <<= 1>) = { } // f: <T> (x: T<N() >>= 1>) = { } // f: <V: T<N() <<= 1>> (x) = { } // f: <V: T<N() >>= 1>> (x) = { } x := y$; x := 0; x = 0; x := 0; xx := 0; xx = 0; x := 0; x: _ = y; xx: _ == y; x: _ == y; x :== y; xx :== y; zero :== int_c<0>; f5: <T> (_: std::vector<T>) = { } f1: () = { v0 := 0; } f2: () = { v0 := cp(0); } f4: (inout v0: i8, v1: * i8) = { v0&* = 1; v1* *= 1; } cp: <T> (x: T) -> T = x; t0: <v0: _> type == i8; t0: <v0: _> final type = { } t0: <v0: _> requires true = 0; main: () -> int = { f3(); // next(u8(255)); v0: i8 = 1; f4(v0, v0&); v: std::vector<int> = (); f5(v); return next(-v0); } x: long long; // Interpolated raw string literal. x := $R"()"; x := $R"(x)"; x := $R"~()~"; x := u8$R"~(x)~"; // Clang Format regression tests. x: Type = (a, 0); f: () = { operator==(this, this); operator[](this, this); x := t<* day>; (x := 0) (move x); (x: t<* t> = g("('(')$")) (move x); :<move V: _> () = {}; } x := (:int = 0); t: type = { operator is: (this, that) -> bool; operator[]: (inout this, x: i32) = { } // When further indented. } f: () = { :() [[pre: 1]] = 0; :() [[pre: 1]] = {}; :() [[pre: 1]] requires 1 = {}; :() [[pre: 1]] = :() = { x; x; }; } f: () = { x * x; x & x; x * as; x * (0); } f: () = { (move x); (:int = 0); (x := 0) (move x); (move x); (); } // `->*` is split into `->` `*`. // f: () -> std::tuple<i32, * (:i32) ->* ()>; f: () = { :int = 0; +x; :int = 0; -x; g(); (); } f: () = { for r do (e) g(e); } f: (is: * ()) = { [[assert: is is is]] [[assert: (is) is (is)]] [[assert: is as * ()]] [[assert: (is) as * ()]] } I<[] { auto y = 0; return y < z; }()> x = 0; x: I<:() -> _ = { y := 0; return y < z; }()> = 0; int_c: <V: int> const std::integral_constant<int, V> = (); x := (type); f3: () = { v0: i8 = 0; v1: i8 = i8(0); v2: i8 = cp(:i8 = 0); v3: i8 = cp(0 as i8); v4: t0<:i8 = 0> = 0; v5 := v0&; v6 := v5*; } // Syntax highlighting test cases. // Highlighted interpolation (I want them formatted, too). x := "Next is (current++)$\n"; x := "(inspect 1->i32{is _=2;})$"; x := "(\"0\")$\n"; // Known limitation. // Type-only contexts. x: i32 = 0; x: int = 0; // Discouraged, not highlighted as a keyword. x: day = Wednesday; x: type == i32; x: type == day; x := x as day; f: () -> day = { } // Types. x := t<i32>; x := t<* day>; x := i32(0); // `_`. // // Anonymous declarations. _: namespace = { } _ := std::lock(mutex); // // Deduced types. x: _ = 0; f: (:_) -> _ = { } // // Placeholder. x := x is _; // // Just an identifier. f: <_> (_) = _; f: () = { // Keyword, declaration, type, identifier. (move move: move = move) { } // Pending [hsutter/cppfront#408][]. } int x = 0; const int* const x = 0; x: i32 = 0; x: const * const i32 = 0; // clang-format off x : i32 = 0 ; x:i32=0; x:const*const i32=0; // clang-format on long int x = 0; x: long int = 0; ::day x = 0; ns::day x = 0; ::t::day x = 0; t<0>::day x = 0; ::t<0>::day x = 0; x: ::day = 0; x: ns::day = 0; x: ::t::day = 0; x: t<0>::day = 0; x: ::t<0>::day = 0; export day x = 0; export x: day = 0; // clang-format off export x: day = 0; // clang-format on exportx: day = 0; x: @x i32 = 0; x: @x::x i32 = 0; x: @x.x i32 = 0; x: @x<T> i32 = 0; x: @x<T>::x i32 = 0; x: @x<T>.x i32 = 0; x: @x <T: type> i32 = 0; x: @x<T> <T: type> i32 = 0; // clang-format off x:@x@x i32=0; x : @ x @ x i32 = 0; // clang-format on template<class T> int x = 0; template<class> day x = 0; x: <T: type> i32 = 0; x: <T> i32 = 0; x: <:type> day = 0; // clang-format off x:<T,T>i32=0; x : < T , T > i32 = 0; // clang-format on template<auto V> int x = 0; template<auto> int x = 0; template<const auto& V> day x = 0; template<const auto&> day x = 0; x: <V: _> i32 = 0; x: <:_> i32 = 0; x: <:__> i32 = 0; x: <in V: _> day = 0; x: <in: _> day = 0; x: <inV: _> day = 0; void f() { } void f(const auto& x) { } void f(const auto&) { } void f(auto) { } void f(const auto) { } void f(const day x) { } void f(const day) { } f: () = { } f: (in x: _) = { } f: (in x) = { } f: (x) = { } f: (in: _) = { } f: (:_) = { } f: (copy: _) = { } f: (copy: const _) = { } f: (in x: day) = { } f: (x: day) = { } f: (in: day) = { } f: (:day) = { } // clang-format off f:(x,y)={} f : ( in x : _ , : day ) = { } f: (in :_) = { } // clang-format on f: (inx: _) = { } f: (inx) = { } f: (:const_) = { } void f() noexcept { } f: () throws = { } // clang-format off f:()throws={} // clang-format on _: throws_ = { } int f() { } day f() { } auto f() { } auto&& f() { } auto f() -> int { } auto f() -> day { } auto f() -> auto { } auto f() -> auto&& { } f: () -> i32 { } f: () -> day { } f: () -> _ { } f: () -> forward _ { } // clang-format off f:()->i32{} f:()->forward _{} f:()->forward_{} // clang-format on auto f() -> move { } auto f() -> ns::move { } auto f() -> ::ns::move { } f: () -> ::move { } f: () -> ns::move { } f: () -> ::ns::move { } f: () [[pre: true]] = { } f: () [[pre: true, ""]] = { } f: () [[pre: true]] [[post: true]] = { } // clang-format off f:()[[pre:true]][[post:true]]={} f : () [ [ pre : true ] ] = { } f : () [ [ pre : true ] ] [ [ post : true ] ] = { } f: () [ [ pre : true ] ] [ [ post : true ] ] = { } // clang-format on f: () [[pre ::x<0>: true]] = { } f: () [[pre Bounds: true]] = { } void f() requires true { } f: () requires true = { } _: requires_ = { } struct t { }; struct t final { }; struct t : base { int x = 0; day x; bool operator==(const t&) const = default; void operator[](int x) { } virtual void f() const = 0; }; t: type = { } t: final type = { } t: type = { x: i32 = 0; x: day; this: base; operator==: (this, that) -> bool; operator[]: (inout this, x_: i32) = { x = x_; this.x = x_; operator==(this, this); this.operator==(this); } f: (virtual in this); // clang-format off x:i32=0; x :day ; this :base ; operator == :( this ,that )->bool ; operator [ ] :( inout this ,x :i32 )={} // clang-format on f: (in this_, that_); f: (virtual_); f: (inthis); f: (virtualthis); f: (virtualinthis); } t: type = { operator is: (this, that) -> bool; } _: final_ = { } _: type_ = { } namespace ns { } ns: namespace = { } // clang-format off ns :namespace={} // clang-format on _: namespace_ = { } x = 0.0e+0f; x := 0.0e+0f; x = 0x0'0u; x := 0x0'0u; x = 0b0'0; x := 0b0'0; x = 0'0; x := 0'0; x = '\0'; x := '\0'; x = nullptr; x := nullptr; x = false; x := false; x = u8""; x := u8""; x = "(x)$"; x := "\(x)$"; x := "(x)$"; x := "(x)$(x)$"; x := "@(x)$@(x)$@"; x = R"()"; x := R"()"; x = u8R"()"; x := u8R"()"; x := $R"()"; x := u8$R"()"; // Highlight interpolation also in non-interpolated raw string literal as it's most likely used for reflection. x = R"((x)$)"; x := $R"(\(x)$)"; x := R"(\(x)$)"; x := R"((x)$)"; x := R"((x)$(x)$)"; x := R"(@(x)$@(x)$@)"; x := "(:()->_=0;())$"; x := "(inspect 1->i32{is _=2;})$"; x = x = x.x = x::x = x<0> = x<0>.x = x<0>::x; x := x = x.x = x::x = x<0> = x<0>.x = x<0>::x; x = (0); x := (0); x := :int = 0; x := (:int = 0); x := (:int = 0;); x := :() -> _ = 0;(); x := :() -> _ = 0;(x, :int = 0); x := :() -> _ = 0;(x, :int = 0;); x = *x = &x; x := x* = x&; x = x[0](0).x; x := x[0](0).x; x = +x; x := +x = move x = +move x; x = x * x + x << x <=> x < x == x & x ^ x | x && x || x; x := x * x + x << x <=> x < x == x & x ^ x | x && x || x; struct t { struct t { }; struct t { int x = 0; void f() { } }; }; t: type = { t: type = { } t: type = { x: i32 = 0; f: () = { } } } namespace ns { int x = 0; void f() { } struct t { int x = 0; void f() { } }; } // namespace ns ns: namespace = { x: i32 = 0; f: () = { } t: type = { x: i32 = 0; f: () = { } } } // namespace ns namespace ns { int x = 0; namespace ns { void f() { } struct t { int x = 0; struct t { void f() { [] {}; } }; }; } // namespace ns } // namespace ns ns: namespace = { x: i32 = 0; ns: namespace = { f: () = { } t: type = { x: i32 = 0; t: type = { f: () = { :() = {}; } } } } // namespace ns } // namespace ns // Cpp1 colons. int x = a ? b : c; int x = a ? // clang-format off b : c; // clang-format on void f() { switch (x) { case x: default: label: goto label; } for (auto x : r) { } } enum t : int; class t : base { public: unsigned x : 1; t() : x{} { } t() requires x : x{} { } t() // clang-format off requires x : x{} { } // clang-format on t() noexcept : x{} { } t() try : x{} { } catch (...) { } t() // clang-format off try : x{} { // clang-format on } catch (...) { } }; module a:b; module: private; int x = a::b; // Cpp2 colons. f: () = { // Contract colons. [[assert: true]] [[assert Bounds: true]] [[assert MyBounds: true]] // Declaration colons. pre: while true { } pre: // while true { } x := 0; x: i32 = 0; :i32 = 0; x :== y; x: _ == y; f: () = { } :() = {}; :(in x: i32) = {}; :(x: i32) = {}; :(in: i32) = {}; // Pending [grammar][]. :(:i32) = {}; // Pending [grammar][]. t: <V: _> type = { x: i32; this: u; operator=: (); operator==: (); operator(): (); operator[]: (); } inspect x { y: is _ = g(); } a::b; } struct t { void f(override) override; // Declaration, keyword. void f(final) final; // Declaration, keyword. }; f: () = { // Declaration followed by keyword. :(implicit, implicit this) = {}; :(override, override this) = {}; :(final, final this) = {}; :(final, final in this) = {}; :(throws) throws = {}; f: (pre) [[pre: 1]] = { } f: (post) [[post: 1]] = { } f: (assert) [[assert: 1]] = { } t: <type> type = { } t: <final> final type = { } t: <type> type requires 1 = { } t: <type> type == i32; :<type: type> () = {}; } f: () = { move; // Identifier. -move; // Identifier. move*; // Identifier. x is move; // Type. x + move x; // Keyword. // Pending [hsutter/cppfront#408][]. x + move; // Identifier. move x; // Keyword. // Pending [hsutter/cppfront#408][]. move move x; // Keywords. // Pending [hsutter/cppfront#408][]. move: i8; // Declaration. x: move; // Type. f(move); // Identifier. x[move]; // Identifier. x[move x]; // Keyword. f(move x, move x); // Keywords. :(move, move) = {}; // Declarations. :(move: i8) = {}; // Keyword. // Pending [grammar][]. :(move x) = {}; // Keyword. :(move x: i8) = {}; // Keyword. :(move move) = {}; // Keyword, declaration. :(move move: i8) = {}; // Keyword, declaration. :(:move) = {}; // Type. :(move: move) = {}; // Keyword, type. // Pending [hsutter/cppfront#408][]. :() -> move i8 = {}; // Keyword. :() -> ::move = {}; // Type. return move x; // Keyword. // Pending [hsutter/cppfront#408][]. :<move V: _> () = {}; // Keyword. // Pending [hsutter/cppfront#425][]. (move move: move = move) { } // Keyword, declaration, type, identifier. // Pending [hsutter/cppfront#408][]. } void f() { x and y; // Keyword. new int; // Keyword. class t; // Keyword. struct t; // Keyword. } f: () = { // Reclaimed identifiers. f(and); f(::new); f(class); f(struct); x := new<i32>(); // Special identifier. x := ::new<i32>(); // Identifier. _ := finally(:() = {}); // Special identifier. _ := ::finally(); // Identifier. [[assert Bounds: min <= x < max]] // Special identifier. [[assert MyBounds: min <= x < max]] // Identifier. } // Highlighting regression tests. // clang-format off x := (0)is 0; // clang-format on t: type = { operatoris: (); } x := "()$ ()"; // [grammar]: https://github.com/hsutter/cppfront/issues/387 // [hsutter/cppfront#408]: https://github.com/hsutter/cppfront/issues/408 // [hsutter/cppfront#425]: https://github.com/hsutter/cppfront/issues/425
cpp2_cppfront source #2
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
cppfront trunk
Options
Source code
f: () = { move; // Identifier. -move; // Identifier. move*; // Identifier. x is move; // Type. x + move x; // Keyword. // Pending [hsutter/cppfront#408][]. x + move; // Identifier. move x; // Keyword. // Pending [hsutter/cppfront#408][]. move move x; // Keywords. // Pending [hsutter/cppfront#408][]. move: i8; // Declaration. x: move; // Type. f(move); // Identifier. x[move]; // Identifier. x[move x]; // Keyword. f(move x, move x); // Keywords. :(move, move) = {}; // Declarations. :(move: i8) = {}; // Keyword. // Pending [grammar][]. :(move x) = {}; // Keyword. :(move x: i8) = {}; // Keyword. :(move move) = {}; // Keyword, declaration. :(move move: i8) = {}; // Keyword, declaration. :(:move) = {}; // Type. :(move: move) = {}; // Keyword, type. // Pending [hsutter/cppfront#408][]. :() -> move i8 = {}; // Keyword. :() -> ::move = {}; // Type. return move x; // Keyword. // Pending [hsutter/cppfront#408][]. :<move V: _> () = {}; // Keyword. // Pending [hsutter/cppfront#425][]. (move move: move = move) { } // Keyword, declaration, type, identifier. // Pending [hsutter/cppfront#408][]. }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Compiler Explorer Shop
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
CE on Bluesky
Statistics
Changelog
Version tree