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: ...@@ -792,7 +792,7 @@ private:
if (type.isBranded()) { if (type.isBranded()) {
name.addMemberType("_capnpPrivate"); name.addMemberType("_capnpPrivate");
name.addMemberValue("brand"); name.addMemberValue("brand");
return kj::strTree(name); return kj::strTree(name, "()");
} else { } else {
return nullptr; return nullptr;
} }
...@@ -1800,7 +1800,7 @@ private: ...@@ -1800,7 +1800,7 @@ private:
"\n" "\n"
"#if !CAPNP_LITE\n" "#if !CAPNP_LITE\n"
" inline ::kj::StringTree toString() const {\n" " inline ::kj::StringTree toString() const {\n"
" return ::capnp::_::structString(_reader, *_capnpPrivate::brand);\n" " return ::capnp::_::structString(_reader, *_capnpPrivate::brand());\n"
" }\n" " }\n"
"#endif // !CAPNP_LITE\n" "#endif // !CAPNP_LITE\n"
"\n", "\n",
...@@ -1891,8 +1891,8 @@ private: ...@@ -1891,8 +1891,8 @@ private:
(!hasBrandDependencies ? "" : (!hasBrandDependencies ? "" :
" static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[];\n"), " static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[];\n"),
" static const ::capnp::_::RawBrandedSchema specificBrand;\n" " static const ::capnp::_::RawBrandedSchema specificBrand;\n"
" static constexpr ::capnp::_::RawBrandedSchema const* brand = " " static constexpr ::capnp::_::RawBrandedSchema const* brand() { "
"::capnp::_::ChooseBrand<_capnpPrivate, ", templateContext.allArgs(), ">::brand;\n"); "return ::capnp::_::ChooseBrand<_capnpPrivate, ", templateContext.allArgs(), ">::brand(); }\n");
} }
kj::StringTree makeGenericDefinitions( kj::StringTree makeGenericDefinitions(
...@@ -1953,8 +1953,7 @@ private: ...@@ -1953,8 +1953,7 @@ private:
templates, "constexpr uint16_t ", fullName, "::_capnpPrivate::pointerCount;\n" templates, "constexpr uint16_t ", fullName, "::_capnpPrivate::pointerCount;\n"
"#if !CAPNP_LITE\n", "#if !CAPNP_LITE\n",
templates, "constexpr ::capnp::Kind ", fullName, "::_capnpPrivate::kind;\n", templates, "constexpr ::capnp::Kind ", fullName, "::_capnpPrivate::kind;\n",
templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n", templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n");
templates, "constexpr ::capnp::_::RawBrandedSchema const* ", fullName, "::_capnpPrivate::brand;\n");
if (templateContext.isGeneric()) { if (templateContext.isGeneric()) {
auto brandInitializers = makeBrandInitializers(templateContext, schema); auto brandInitializers = makeBrandInitializers(templateContext, schema);
...@@ -1970,7 +1969,7 @@ private: ...@@ -1970,7 +1969,7 @@ private:
} else { } else {
declareText = kj::strTree(kj::mv(declareText), declareText = kj::strTree(kj::mv(declareText),
" #if !CAPNP_LITE\n" " #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"); " #endif // !CAPNP_LITE\n");
} }
...@@ -2228,8 +2227,7 @@ private: ...@@ -2228,8 +2227,7 @@ private:
"// ", fullName, "\n", "// ", fullName, "\n",
"#if !CAPNP_LITE\n", "#if !CAPNP_LITE\n",
templates, "constexpr ::capnp::Kind ", fullName, "::_capnpPrivate::kind;\n", templates, "constexpr ::capnp::Kind ", fullName, "::_capnpPrivate::kind;\n",
templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n", templates, "constexpr ::capnp::_::RawSchema const* ", fullName, "::_capnpPrivate::schema;\n");
templates, "constexpr ::capnp::_::RawBrandedSchema const* ", fullName, "::_capnpPrivate::brand;\n");
if (templateContext.isGeneric()) { if (templateContext.isGeneric()) {
auto brandInitializers = makeBrandInitializers(templateContext, schema); auto brandInitializers = makeBrandInitializers(templateContext, schema);
...@@ -2242,7 +2240,7 @@ private: ...@@ -2242,7 +2240,7 @@ private:
makeGenericDefinitions(templates, fullName, kj::str(hexId), kj::mv(brandInitializers))); makeGenericDefinitions(templates, fullName, kj::str(hexId), kj::mv(brandInitializers)));
} else { } else {
declareText = kj::strTree(kj::mv(declareText), 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"); declareText = kj::strTree(kj::mv(declareText), " };\n #endif // !CAPNP_LITE");
...@@ -2644,7 +2642,8 @@ private: ...@@ -2644,7 +2642,8 @@ private:
kj::StringTree(KJ_MAP(index, membersByDiscrim) { return kj::strTree(index); }, ", "), kj::StringTree(KJ_MAP(index, membersByDiscrim) { return kj::strTree(index); }, ", "),
"};\n"), "};\n"),
brandDeps.size() == 0 ? kj::strTree() : kj::strTree( 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" "const ::capnp::_::RawSchema s_", hexId, " = {\n"
" 0x", hexId, ", b_", hexId, ".words, ", rawSchema.size(), ", ", " 0x", hexId, ", b_", hexId, ".words, ", rawSchema.size(), ", ",
deps.size() == 0 ? kj::strTree("nullptr") : kj::strTree("d_", hexId), ", ", 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