Commit bcd9e553 authored by Kenton Varda's avatar Kenton Varda

Work around Clang and GCC disagreeing on name mangling.

Specifically, consider:

    capnp::BuilderFor<capnp::DynamicStruct> capnp::Orphan<capnp::AnyPointer>::getAs<capnp::DynamicStruct>(capnp::StructSchema)

Note that `BuilderFor` is a "template using" directive which expands into something more complicated.

GCC mangles the symbol as:

    _ZN5capnp6OrphanINS_10AnyPointerEE5getAsINS_13DynamicStructEEENS_11BuilderFor_IT_Xcl4kindIS6_EEEE4TypeENS_12StructSchemaE

Which `c++filt` decodes as:

    capnp::BuilderFor_<capnp::DynamicStruct, (kind<capnp::DynamicStruct>)()>::Type capnp::Orphan<capnp::AnyPointer>::getAs<capnp::DynamicStruct>(capnp::StructSchema)

Note that `BuilderFor_<...>::Type` here ends up being a typedef for `DynamicStruct::Builder`. It seems weird to me that the symbol name would not substitute this typedef.

Clang, meanwhile, mangles the symbol as:

    _ZN5capnp6OrphanINS_10AnyPointerEE5getAsINS_13DynamicStructEEENS_11BuilderFor_IT_Xclgssr5capnpE4kindIS6_EEEE4TypeENS_12StructSchemaE

Which `c++filt` does not seem to be able to demangle at all. But, it looks like `capnp::kind` is in there, suggesting that, again, the typedef wasn't substituted.

I don't know who is right, but if we inline the whole thing, the problem goes away.
parent 880bbbbe
......@@ -1953,52 +1953,17 @@ void AnyPointer::Builder::adopt<DynamicValue>(Orphan<DynamicValue>&& orphan) {
}
}
template <>
DynamicStruct::Builder Orphan<AnyPointer>::getAs<DynamicStruct>(StructSchema schema) {
return DynamicStruct::Builder(schema, builder.asStruct(structSizeFromSchema(schema)));
}
template <>
DynamicStruct::Reader Orphan<AnyPointer>::getAsReader<DynamicStruct>(StructSchema schema) const {
return DynamicStruct::Reader(schema, builder.asStructReader(structSizeFromSchema(schema)));
}
template <>
Orphan<DynamicStruct> Orphan<AnyPointer>::releaseAs<DynamicStruct>(StructSchema schema) {
return Orphan<DynamicStruct>(schema, kj::mv(builder));
}
template <>
DynamicList::Builder Orphan<AnyPointer>::getAs<DynamicList>(ListSchema schema) {
if (schema.whichElementType() == schema::Type::STRUCT) {
return DynamicList::Builder(schema, builder.asStructList(
structSizeFromSchema(schema.getStructElementType())));
} else {
return DynamicList::Builder(schema, builder.asList(elementSizeFor(schema.whichElementType())));
}
}
template <>
DynamicList::Reader Orphan<AnyPointer>::getAsReader<DynamicList>(ListSchema schema) const {
return DynamicList::Reader(schema, builder.asListReader(
elementSizeFor(schema.whichElementType())));
}
template <>
Orphan<DynamicList> Orphan<AnyPointer>::releaseAs<DynamicList>(ListSchema schema) {
return Orphan<DynamicList>(schema, kj::mv(builder));
}
template <>
DynamicCapability::Client Orphan<AnyPointer>::getAs<DynamicCapability>(InterfaceSchema schema) {
return DynamicCapability::Client(schema, builder.asCapability());
}
template <>
DynamicCapability::Client Orphan<AnyPointer>::getAsReader<DynamicCapability>(
InterfaceSchema schema) const {
return DynamicCapability::Client(schema, builder.asCapability());
}
template <>
Orphan<DynamicCapability> Orphan<AnyPointer>::releaseAs<DynamicCapability>(
InterfaceSchema schema) {
return Orphan<DynamicCapability>(schema, kj::mv(builder));
}
DynamicStruct::Reader::Reader(StructSchema schema, const _::OrphanBuilder& orphan)
: schema(schema), reader(orphan.asStructReader(structSizeFromSchema(schema))) {}
DynamicStruct::Builder::Builder(StructSchema schema, _::OrphanBuilder& orphan)
: schema(schema), builder(orphan.asStruct(structSizeFromSchema(schema))) {}
DynamicList::Reader::Reader(ListSchema schema, const _::OrphanBuilder& orphan)
: schema(schema), reader(orphan.asListReader(elementSizeFor(schema.whichElementType()))) {}
DynamicList::Builder::Builder(ListSchema schema, _::OrphanBuilder& orphan)
: schema(schema), builder(schema.whichElementType() == schema::Type::STRUCT
? orphan.asStructList(structSizeFromSchema(schema.getStructElementType()))
: orphan.asList(elementSizeFor(schema.whichElementType()))) {}
// -------------------------------------------------------------------
......
......@@ -214,6 +214,7 @@ private:
inline Reader(StructSchema schema, _::StructReader reader)
: schema(schema), reader(reader) {}
Reader(StructSchema schema, const _::OrphanBuilder& orphan);
bool isSetInUnion(StructSchema::Field field) const;
void verifySetInUnion(StructSchema::Field field) const;
......@@ -305,6 +306,7 @@ private:
inline Builder(StructSchema schema, _::StructBuilder builder)
: schema(schema), builder(builder) {}
Builder(StructSchema schema, _::OrphanBuilder& orphan);
bool isSetInUnion(StructSchema::Field field);
void verifySetInUnion(StructSchema::Field field);
......@@ -381,6 +383,7 @@ private:
_::ListReader reader;
Reader(ListSchema schema, _::ListReader reader): schema(schema), reader(reader) {}
Reader(ListSchema schema, const _::OrphanBuilder& orphan);
template <typename T, Kind k>
friend struct _::PointerHelpers;
......@@ -431,6 +434,7 @@ private:
_::ListBuilder builder;
Builder(ListSchema schema, _::ListBuilder builder): schema(schema), builder(builder) {}
Builder(ListSchema schema, _::OrphanBuilder& orphan);
template <typename T, Kind k>
friend struct _::PointerHelpers;
......@@ -1186,26 +1190,48 @@ inline Orphan<T> AnyPointer::Builder::disownAs(InterfaceSchema schema) {
return _::PointerHelpers<T>::disown(builder, schema);
}
// We have to declare the methods below inline because Clang and GCC disagree about how to mangle
// their symbol names.
template <>
DynamicStruct::Builder Orphan<AnyPointer>::getAs<DynamicStruct>(StructSchema schema);
inline DynamicStruct::Builder Orphan<AnyPointer>::getAs<DynamicStruct>(StructSchema schema) {
return DynamicStruct::Builder(schema, builder);
}
template <>
DynamicList::Builder Orphan<AnyPointer>::getAs<DynamicList>(ListSchema schema);
inline DynamicStruct::Reader Orphan<AnyPointer>::getAsReader<DynamicStruct>(
StructSchema schema) const {
return DynamicStruct::Reader(schema, builder);
}
template <>
DynamicCapability::Client Orphan<AnyPointer>::getAs<DynamicCapability>(InterfaceSchema schema);
inline Orphan<DynamicStruct> Orphan<AnyPointer>::releaseAs<DynamicStruct>(StructSchema schema) {
return Orphan<DynamicStruct>(schema, kj::mv(builder));
}
template <>
DynamicStruct::Reader Orphan<AnyPointer>::getAsReader<DynamicStruct>(StructSchema schema) const;
inline DynamicList::Builder Orphan<AnyPointer>::getAs<DynamicList>(ListSchema schema) {
return DynamicList::Builder(schema, builder);
}
template <>
DynamicList::Reader Orphan<AnyPointer>::getAsReader<DynamicList>(ListSchema schema) const;
inline DynamicList::Reader Orphan<AnyPointer>::getAsReader<DynamicList>(ListSchema schema) const {
return DynamicList::Reader(schema, builder);
}
template <>
DynamicCapability::Client Orphan<AnyPointer>::getAsReader<DynamicCapability>(
InterfaceSchema schema) const;
inline Orphan<DynamicList> Orphan<AnyPointer>::releaseAs<DynamicList>(ListSchema schema) {
return Orphan<DynamicList>(schema, kj::mv(builder));
}
template <>
Orphan<DynamicStruct> Orphan<AnyPointer>::releaseAs<DynamicStruct>(StructSchema schema);
inline DynamicCapability::Client Orphan<AnyPointer>::getAs<DynamicCapability>(
InterfaceSchema schema) {
return DynamicCapability::Client(schema, builder.asCapability());
}
template <>
Orphan<DynamicList> Orphan<AnyPointer>::releaseAs<DynamicList>(ListSchema schema);
inline DynamicCapability::Client Orphan<AnyPointer>::getAsReader<DynamicCapability>(
InterfaceSchema schema) const {
return DynamicCapability::Client(schema, builder.asCapability());
}
template <>
Orphan<DynamicCapability> Orphan<AnyPointer>::releaseAs<DynamicCapability>(
InterfaceSchema schema);
inline Orphan<DynamicCapability> Orphan<AnyPointer>::releaseAs<DynamicCapability>(
InterfaceSchema schema) {
return Orphan<DynamicCapability>(schema, kj::mv(builder));
}
// =======================================================================================
// Inline implementation details.
......
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