Commit 1572e754 authored by Harris Hancock's avatar Harris Hancock

Convert brand-pointer to constexpr-function (1/3)

MSVC erroneously refuses to compile code which calculates the address of
objects of static storage duration at compile-time, despite this being
legal. Work around this by changing `_capnpPrivate::brand` from constexpr
pointers to static constexpr functions returning pointers. The compiler
is then free to calculate it at compile-time if it can (gcc, clang), but
can also defer it to run-time if it can't (MSVC).

This change is split into three commits:

1. Changes to the code generator (this commit).
2. A bootstrap regeneration, after which the codebase will not compile.
3. Changes to the generated code support header, after which the codebase
will again compile.
parent b2e23c1a
......@@ -792,7 +792,7 @@ private:
if (type.isBranded()) {
name.addMemberType("_capnpPrivate");
name.addMemberValue("brand");
return kj::strTree(name);
return kj::strTree(name, "()");
} else {
return nullptr;
}
......@@ -1800,7 +1800,7 @@ private:
"\n"
"#if !CAPNP_LITE\n"
" inline ::kj::StringTree toString() const {\n"
" return ::capnp::_::structString(_reader, *_capnpPrivate::brand);\n"
" return ::capnp::_::structString(_reader, *_capnpPrivate::brand());\n"
" }\n"
"#endif // !CAPNP_LITE\n"
"\n",
......@@ -1891,8 +1891,8 @@ private:
(!hasBrandDependencies ? "" :
" static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[];\n"),
" static const ::capnp::_::RawBrandedSchema specificBrand;\n"
" static constexpr ::capnp::_::RawBrandedSchema const* brand = "
"::capnp::_::ChooseBrand<_capnpPrivate, ", templateContext.allArgs(), ">::brand;\n");
" static constexpr ::capnp::_::RawBrandedSchema const* brand() { "
"return ::capnp::_::ChooseBrand<_capnpPrivate, ", templateContext.allArgs(), ">::brand(); }\n");
}
kj::StringTree makeGenericDefinitions(
......@@ -1953,8 +1953,7 @@ private:
templates, "constexpr uint16_t ", fullName, "::_capnpPrivate::pointerCount;\n"
"#if !CAPNP_LITE\n",
templates, "constexpr ::capnp::Kind ", fullName, "::_capnpPrivate::kind;\n",
templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n",
templates, "constexpr ::capnp::_::RawBrandedSchema const* ", fullName, "::_capnpPrivate::brand;\n");
templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n");
if (templateContext.isGeneric()) {
auto brandInitializers = makeBrandInitializers(templateContext, schema);
......@@ -1970,7 +1969,7 @@ private:
} else {
declareText = kj::strTree(kj::mv(declareText),
" #if !CAPNP_LITE\n"
" static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand;\n"
" static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }\n"
" #endif // !CAPNP_LITE\n");
}
......@@ -2228,8 +2227,7 @@ private:
"// ", fullName, "\n",
"#if !CAPNP_LITE\n",
templates, "constexpr ::capnp::Kind ", fullName, "::_capnpPrivate::kind;\n",
templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n",
templates, "constexpr ::capnp::_::RawBrandedSchema const* ", fullName, "::_capnpPrivate::brand;\n");
templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n");
if (templateContext.isGeneric()) {
auto brandInitializers = makeBrandInitializers(templateContext, schema);
......@@ -2242,7 +2240,7 @@ private:
makeGenericDefinitions(templates, fullName, kj::str(hexId), kj::mv(brandInitializers)));
} else {
declareText = kj::strTree(kj::mv(declareText),
" static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand;\n");
" static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }\n");
}
declareText = kj::strTree(kj::mv(declareText), " };\n #endif // !CAPNP_LITE");
......@@ -2644,7 +2642,8 @@ private:
kj::StringTree(KJ_MAP(index, membersByDiscrim) { return kj::strTree(index); }, ", "),
"};\n"),
brandDeps.size() == 0 ? kj::strTree() : kj::strTree(
"const ::capnp::_::RawBrandedSchema::Dependency bd_", hexId, "[] = ", kj::mv(brandDeps), ";\n"),
"KJ_CONSTEXPR(const) ::capnp::_::RawBrandedSchema::Dependency bd_", hexId, "[] = ",
kj::mv(brandDeps), ";\n"),
"const ::capnp::_::RawSchema s_", hexId, " = {\n"
" 0x", hexId, ", b_", hexId, ".words, ", rawSchema.size(), ", ",
deps.size() == 0 ? kj::strTree("nullptr") : kj::strTree("d_", hexId), ", ",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment