Commit 4b4b921d authored by Harris Hancock's avatar Harris Hancock

Hard-code dependency/scope counts in generated code (1/2)

MSVC cannot deduce sizes of arrays defined inside class templates.

Bootstrap regeneration commit to follow.
parent 08a6b91f
...@@ -677,6 +677,14 @@ private: ...@@ -677,6 +677,14 @@ private:
kj::StringTree scopes; kj::StringTree scopes;
kj::StringTree bindings; kj::StringTree bindings;
kj::StringTree dependencies; kj::StringTree dependencies;
size_t dependencyCount;
// TODO(msvc): `dependencyCount` is the number of individual dependency definitions in
// `dependencies`. It's a hack to allow makeGenericDefinitions to hard-code the size of the
// `_capnpPrivate::brandDependencies` array into the definition of
// `_capnpPrivate::specificBrand::dependencyCount`. This is necessary because MSVC cannot deduce
// the size of `brandDependencies` if it is nested under a class template. It's probably this
// demoralizingly deferred bug:
// https://connect.microsoft.com/VisualStudio/feedback/details/759407/can-not-get-size-of-static-array-defined-in-class-template
}; };
BrandInitializerText makeBrandInitializers( BrandInitializerText makeBrandInitializers(
...@@ -699,15 +707,20 @@ private: ...@@ -699,15 +707,20 @@ private:
} }
} }
auto depMap = makeBrandDepMap(templateContext, schema);
auto dependencyCount = depMap.size();
return { return {
kj::strTree("{\n", scopes.finish(), "}"), kj::strTree("{\n", scopes.finish(), "}"),
kj::strTree("{\n", bindings.releaseAsArray(), "}"), kj::strTree("{\n", bindings.releaseAsArray(), "}"),
makeBrandDepInitializers(templateContext, schema) makeBrandDepInitializers(kj::mv(depMap)),
dependencyCount
}; };
} }
kj::StringTree makeBrandDepInitializers(const TemplateContext& templateContext, Schema schema) { std::map<uint, kj::StringTree>
// Build deps. Returns a braced initialiser list, or an empty string if there are no dependencies. makeBrandDepMap(const TemplateContext& templateContext, Schema schema) {
// Build deps. This is separate from makeBrandDepInitializers to give calling code the
// opportunity to count the number of dependencies, to calculate array sizes.
std::map<uint, kj::StringTree> depMap; std::map<uint, kj::StringTree> depMap;
#define ADD_DEP(kind, index, ...) \ #define ADD_DEP(kind, index, ...) \
...@@ -749,7 +762,12 @@ private: ...@@ -749,7 +762,12 @@ private:
break; break;
} }
#undef ADD_DEP #undef ADD_DEP
return depMap;
}
kj::StringTree makeBrandDepInitializers(std::map<uint, kj::StringTree>&& depMap) {
// Process depMap. Returns a braced initialiser list, or an empty string if there are no
// dependencies.
if (!depMap.size()) { if (!depMap.size()) {
return kj::strTree(); return kj::strTree();
} }
...@@ -1896,11 +1914,16 @@ private: ...@@ -1896,11 +1914,16 @@ private:
} }
kj::StringTree makeGenericDefinitions( kj::StringTree makeGenericDefinitions(
kj::StringPtr templates, kj::StringPtr fullName, kj::StringPtr hexId, const TemplateContext& templateContext, kj::StringPtr fullName, kj::StringPtr hexId,
BrandInitializerText brandInitializers) { BrandInitializerText brandInitializers) {
// Returns the definitions for the members from makeGenericDeclarations(). // Returns the definitions for the members from makeGenericDeclarations().
bool hasBrandDependencies = (brandInitializers.dependencies.size() != 0); bool hasBrandDependencies = (brandInitializers.dependencies.size() != 0);
auto scopeCount = templateContext.getScopeMap().size();
auto dependencyCount = brandInitializers.dependencyCount;
kj::String templates = kj::str(templateContext.allDecls());
return kj::strTree( return kj::strTree(
templates, "const ::capnp::_::RawBrandedSchema::Scope ", fullName, templates, "const ::capnp::_::RawBrandedSchema::Scope ", fullName,
"::_capnpPrivate::brandScopes[] = ", kj::mv(brandInitializers.scopes), ";\n", "::_capnpPrivate::brandScopes[] = ", kj::mv(brandInitializers.scopes), ";\n",
...@@ -1916,8 +1939,7 @@ private: ...@@ -1916,8 +1939,7 @@ private:
templates, "const ::capnp::_::RawBrandedSchema ", fullName, "::_capnpPrivate::specificBrand = {\n", templates, "const ::capnp::_::RawBrandedSchema ", fullName, "::_capnpPrivate::specificBrand = {\n",
" &::capnp::schemas::s_", hexId, ", brandScopes, ", " &::capnp::schemas::s_", hexId, ", brandScopes, ",
(!hasBrandDependencies ? "nullptr" : "brandDependencies"), ",\n", (!hasBrandDependencies ? "nullptr" : "brandDependencies"), ",\n",
" sizeof(brandScopes) / sizeof(brandScopes[0]), ", " ", scopeCount, ", ", dependencyCount,
(!hasBrandDependencies ? "0" : "sizeof(brandDependencies) / sizeof(brandDependencies[0])"),
", nullptr\n" ", nullptr\n"
"};\n"); "};\n");
} }
...@@ -1965,7 +1987,8 @@ private: ...@@ -1965,7 +1987,8 @@ private:
" #endif // !CAPNP_LITE\n"); " #endif // !CAPNP_LITE\n");
defineText = kj::strTree(kj::mv(defineText), defineText = kj::strTree(kj::mv(defineText),
makeGenericDefinitions(templates, fullName, kj::str(hexId), kj::mv(brandInitializers))); makeGenericDefinitions(
templateContext, fullName, kj::str(hexId), kj::mv(brandInitializers)));
} else { } else {
declareText = kj::strTree(kj::mv(declareText), declareText = kj::strTree(kj::mv(declareText),
" #if !CAPNP_LITE\n" " #if !CAPNP_LITE\n"
...@@ -2237,7 +2260,8 @@ private: ...@@ -2237,7 +2260,8 @@ private:
makeGenericDeclarations(templateContext, hasDeps)); makeGenericDeclarations(templateContext, hasDeps));
defineText = kj::strTree(kj::mv(defineText), defineText = kj::strTree(kj::mv(defineText),
makeGenericDefinitions(templates, fullName, kj::str(hexId), kj::mv(brandInitializers))); makeGenericDefinitions(
templateContext, 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() { return &schema->defaultBrand; }\n"); " static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }\n");
...@@ -2619,7 +2643,8 @@ private: ...@@ -2619,7 +2643,8 @@ private:
break; break;
} }
auto brandDeps = makeBrandDepInitializers(templateContext, schema.getGeneric()); auto brandDeps = makeBrandDepInitializers(
makeBrandDepMap(templateContext, schema.getGeneric()));
auto schemaDef = kj::strTree( auto schemaDef = kj::strTree(
"static const ::capnp::_::AlignedData<", rawSchema.size(), "> b_", hexId, " = {\n" "static const ::capnp::_::AlignedData<", rawSchema.size(), "> b_", hexId, " = {\n"
......
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