Skip to content

cpp: escape keywords in parameters #1419

@ricochet

Description

@ricochet

I bumped into this when generating bindings for wasi:http with the cpp generator.

The best fix appears to be to use the existing c escape function in C++ since it already includes C++ keywords in addition to C.

Simple repro:

// Test file for C++ code generation fixes:
// 1. C++ keyword escaping (parameter named 'this')
// 2. Forward declarations for resources

package test:cpp-http-owned;

world cpp-http-owned {
  // Test 1: Resource with forward reference
  // IncomingBody returns FutureTrailers (forward declaration needed)
  import test-interface: interface {
    resource incoming-body {
      // Static method with 'this' parameter (C++ keyword)
      finish: static func(this: incoming-body) -> future-trailers;
    }

    resource future-trailers {
      get: func() -> option<string>;
    }

    resource request {
      // Method that returns another resource (forward declaration test)
      consume: func() -> incoming-body;
    }
  }

  // Test 2: Export interface with Owned types
  export test-exports: interface {
    resource request-data {
      constructor();
    }

    resource response {
      constructor();
    }

    // Function requiring ::Owned syntax
    handle: func(req: request-data, resp: response);
  }

  // More C++ keywords as parameters
  export keyword-test: func(this: string, class: u32, template: bool) -> string;
}
Testing if `/opt/wasi-sdk-28.0-arm64-macos/bin/wasm32-wasip2-clang++` works...
Running 82 codegen tests:
........................................................................F.........
------ Failure: tests/codegen/cpp-http-owned.wit --------
  language: cpp
  variant: cpp-http-owned.wit
  error: failed to codegen test for `cpp` over "tests/codegen/cpp-http-owned.wit"
  
  Caused by:
      0: failed to verify generated bindings
      1: command execution failed
         command: "/opt/wasi-sdk-28.0-arm64-macos/bin/wasm32-wasip2-clang++" "/Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned.cpp" "-I" "/Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings" "-I" "/Users/bhayes/repos/bytecodealliance/wit-bindgen/crates/cpp/test_headers" "-Wall" "-Wextra" "-Werror" "-Wc++-compat" "-Wno-unused-parameter" "-std=c++20" "-c" "-o" "/Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/tmp.o"
         status: exit status: 1
         stderr:
           In file included from /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned.cpp:11:
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned_cpp.h:21:67: error: invalid parameter name: 'this' is a keyword
              21 |       static FutureTrailers Finish(cpp_http_owned::IncomingBody&& this);
                 |                                                                   ^
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned_cpp.h:53:41: error: invalid parameter name: 'this' is a keyword
              53 |     wit::string KeywordTest(wit::string this, uint32_t class, bool template);
                 |                                         ^
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned_cpp.h:53:56: error: declaration of anonymous class must be a definition
              53 |     wit::string KeywordTest(wit::string this, uint32_t class, bool template);
                 |                                                        ^
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned_cpp.h:53:63: error: cannot combine with previous 'type-name' declaration specifier
              53 |     wit::string KeywordTest(wit::string this, uint32_t class, bool template);
                 |                                                               ^
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned_cpp.h:53:68: error: invalid parameter name: 'template' is a keyword
              53 |     wit::string KeywordTest(wit::string this, uint32_t class, bool template);
                 |                                                                    ^
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned.cpp:68:112: error: invalid parameter name: 'this' is a keyword
              68 | test::cpp_http_owned::FutureTrailers test::cpp_http_owned::IncomingBody::Finish(cpp_http_owned::IncomingBody&& this)
                 |                                                                                                                ^
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned.cpp:70:66: error: invalid use of 'this' outside of a non-static member function
              70 |   auto ret = test_interfaceX00X5BstaticX5Dincoming_bodyX2Efinish(this.into_handle());
                 |                                                                  ^
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned.cpp:113:113: error: too many arguments to function call, expected 2, have 3
             113 |   auto result1 = exports::cpp_http_owned::KeywordTest(wit::string((char const*)(arg0), len0), (uint32_t(arg2)), (bool(arg3)));
                 |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                           ^~~~~~~~~~~~
           /Users/bhayes/repos/bytecodealliance/wit-bindgen/target/artifacts/codegen/cpp/cpp-http-owned.wit/bindings/cpp_http_owned_cpp.h:53:17: note: 'KeywordTest' declared here
              53 |     wit::string KeywordTest(wit::string this, uint32_t class, bool template);
                 |                 ^           ~~~~~~~~~~~~~~~~~~~~~~~~~~
           8 errors generated.
           
1 tests FAILED

Metadata

Metadata

Assignees

Labels

gen-cppRelated to the C++ code generator

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions