This is an archive of the discontinued LLVM Phabricator instance.

Make TrailingObjects private inheritance of TrailingObjectsImpl protected
AbandonedPublic

Authored by hughbe on Jan 26 2017, 8:16 AM.

Details

Reviewers
jyknight
rsmith
Summary

There is an MSVC bug, that caused build errors porting the Swift compiler to Windows, involving trailing objects.

Example code is

class Identifier {};
class SourceLoc {};

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

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

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

source_file.cpp(180): error C2751: 'llvm::TrailingObjects<BaseTy,TrailingTys...>::operator OverloadToken': the name of a function parameter cannot be qualified
source_file.cpp(190): note: see reference to class template instantiation 'TrailingCallArguments<Derived>' being compiled
source_file.cpp(180): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
source_file.cpp(185): error C2751: 'llvm::TrailingObjects<BaseTy,TrailingTys...>::operator OverloadToken': the name of a function parameter cannot be qualified
source_file.cpp(185): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
source_file.cpp(185): error C2535: 'size_t TrailingCallArguments<Derived>::numTrailingObjects(int) const': member function already defined or declared
source_file.cpp(179): note: see declaration of 'TrailingCallArguments<Derived>::numTrailingObjects'

There is a connect bug here: https://connect.microsoft.com/VisualStudio/feedback/details/3116517

The fix for this MSVC bug (that will likely be unresolved by VS 2017 is to directly refer to

llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken<Identifier>

However, this requires us to give protected acess to TrailingObjectsBase.

I'm creating this revision, because Jordan Rose (Swift engineer at Apple) suggested I discuss this upstream.
You can see discussion with various members of the community here: https://github.com/apple/swift-llvm/pull/33
You can see the suggestion to bring discussion upstream here: https://github.com/apple/swift-llvm/pull/43
You can see the fix here: https://github.com/apple/swift/pull/5948, https://github.com/apple/swift/pull/5948/files#diff-323bdb4c6d842e3b3cd3b40e628c9771R669

Let me know what you think - it's brittle, but necessary to use TrailingObjects effectively in a generic context with MSVC.

Diff Detail

Event Timeline

hughbe created this revision.Jan 26 2017, 8:16 AM
jordan_rose edited reviewers, added: jyknight, rsmith; removed: llvm-commits.Feb 7 2017, 7:26 PM
jyknight edited edge metadata.Feb 12 2017, 8:41 PM

I believe I have an alternative fix which doesn't require users to use trailing_objects_internal, in D29880.

hughbe abandoned this revision.Feb 12 2017, 8:56 PM

Your change looks much nicer - I'll handle updating apple/swift-llvm and apple/swift! Thanks