Problems inheriting from TrailingObjects problems with Visual C++

I’m trying to port Swift to MSVC, and have pretty much got there, apart from one irritating MSVC bug.

Consider the following code:

#include “llvm/Support/TrailingObjects.h”

class SourceLoc {};
class Identifier {};

template
class TrailingCallArguments
: private llvm::TrailingObjects<Derived, SourceLoc, Identifier> {
friend TrailingObjects;

size_t numTrailingObjects(
typename TrailingObjects::template OverloadToken) const {
return 1;
}

size_t numTrailingObjects(
typename TrailingObjects::template OverloadToken) const {
return 2;
}
};

int main() {
TrailingCallArguments();

return 0;
}

Clang/GCC compile this fine. MSVC doesn’t (sorry for the long dump of text here):

1>consoleapplication1.cpp(13): error C2751: ‘llvm::TrailingObjects<BaseTy,TrailingTys…>::operator OverloadToken’: the name of a function parameter cannot be qualified
1> consoleapplication1.cpp(21): note: see reference to class template instantiation ‘TrailingCallArguments’ being compiled
1>consoleapplication1.cpp(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>consoleapplication1.cpp(18): error C2751: ‘llvm::TrailingObjects<BaseTy,TrailingTys…>::operator OverloadToken’: the name of a function parameter cannot be qualified
1>consoleapplication1.cpp(18): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>consoleapplication1.cpp(18): error C2535: ‘size_t TrailingCallArguments::numTrailingObjects(int) const’: member function already defined or declared
1> consoleapplication1.cpp(12): note: see declaration of ‘TrailingCallArguments::numTrailingObjects’
1>consoleapplication1.cpp(13): error C2248: ‘llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken’: cannot access inaccessible struct declared in class ‘llvm::trailing_objects_internal::TrailingObjectsBase’
1> with
1> [
1> NextTy=SourceLoc
1> ]
1> c:\users\hughb\documents\llvm\source\include\llvm\support\trailingobjects.h(168): note: see declaration of ‘llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken’
1> with
1> [
1> NextTy=SourceLoc
1> ]
1> c:\users\hughb\documents\llvm\source\include\llvm\support\trailingobjects.h(81): note: see declaration of ‘llvm::trailing_objects_internal::TrailingObjectsBase’
1> consoleapplication1.cpp(25): note: see reference to class template instantiation ‘TrailingCallArguments’ being compiled
1>consoleapplication1.cpp(18): error C2248: ‘llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken’: cannot access inaccessible struct declared in class ‘llvm::trailing_objects_internal::TrailingObjectsBase’
1> with
1> [
1> NextTy=Identifier
1> ]
1> c:\users\hughb\documents\llvm\source\include\llvm\support\trailingobjects.h(168): note: see declaration of ‘llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken’
1> with
1> [
1> NextTy=Identifier
1> ]
1> c:\users\hughb\documents\llvm\source\include\llvm\support\trailingobjects.h(81): note: see declaration of ‘llvm::trailing_objects_internal::TrailingObjectsBase’

There’s a workaround. It’s ugly, and involves modifying LLVM here: https://github.com/apple/swift-llvm/pull/33 and then modifying the typename termplate stuff: https://github.com/apple/swift/pull/5948/files#diff-323bdb4c6d842e3b3cd3b40e628c9771R669

This is brittle and ugly. Is there a better work around for this MSVC compiler bug that LLVM folks can suggest, considering your expertise in LLVM!
The problem goes away if you change the inheritance of TrailingObjects to have a non-generic BaseType

  • Hugh