This is an archive of the discontinued LLVM Phabricator instance.

MS ABI: Implement #pragma vtordisp() and clang-cl /vdN
ClosedPublic

Authored by rnk on Feb 11 2014, 3:05 PM.

Details

Summary

These features are new in VS 2013 and are necessary in order to layout
std::ostream correctly. Currently we have an ABI incompatibility when
self-hosting with the 2013 stdlib in our convertible_fwd_ostream wrapper
in gtest.

This change adds another implicit attribute, MSVtorDispAttr, because
implicit attributes are currently the best way to make sure the
information stays on class templates through instantiation.

Diff Detail

Event Timeline

majnemer added inline comments.Feb 11 2014, 4:45 PM
include/clang/Driver/CLCompatOptions.td
121 ↗(On Diff #7007)

Can we have a test in test/Driver/cl-options.c for checking that -vd works?

Also, my cl doesn't allow stuff like cl -vd1 -vd2 q.cpp. It errors with:

'/vd1' and '/vd2' command-line options are incompatible

lib/AST/RecordLayoutBuilder.cpp
2729 ↗(On Diff #7007)

Would it be better to use a symbolic constant instead of magic numbers?

lib/Driver/Tools.cpp
4051 ↗(On Diff #7007)

I didn't think aliases needed special handling.

lib/Parse/ParsePragma.cpp
192 ↗(On Diff #7007)

This seems a bit unusual compared to the other #pragma implementations. Looking at the very similar Parser::HandlePragmaPack, it consumes a single token which contains a pointer to useful data. A similar approach should make the implementation of Parser::HandlePragmaMSVtorDisp simpler.

majnemer added inline comments.Feb 11 2014, 10:08 PM
lib/Driver/Tools.cpp
4051 ↗(On Diff #7007)

Nevermind, got confused about something else.

lib/Sema/SemaAttr.cpp
133 ↗(On Diff #7007)

This if and the one that follows don't need braces around their statements.

lib/Sema/SemaDecl.cpp
11214 ↗(On Diff #7007)

This change looks superfluous.

12142 ↗(On Diff #7007)

As does this one.

rnk added inline comments.Feb 12 2014, 12:39 PM
include/clang/Driver/CLCompatOptions.td
121 ↗(On Diff #7007)

We already have a test to make sure we accept /vdN without error. I don't think it's worth a separate process invocation in every test suite run just to make sure that tablegen aliases work.

lib/AST/RecordLayoutBuilder.cpp
2729 ↗(On Diff #7007)

Sure.

lib/Parse/ParsePragma.cpp
192 ↗(On Diff #7007)

HandlePragmaPack is somewhat simple, but the other side has to use the PP allocator and placement new to push the magic token, which is gross. Why not just push the integer or identifier token in question and let the parser consume tokens like it normally would? Also, pragma pack doesn't do any error handling if the integer value is bogus, which is half of the complexity here.

Long term, I think the pragma handlers in parse should receive a reference to Sema or Parser so they don't need to inject tokens. Then we can handle things like:

struct A {
  virtual void f(); 
#pragma vtordisp(0)
   struct B : virtual A { virtual void f(); };
};

Today we error our because the annotations don't appear at the right places in our grammar.

lib/Sema/SemaAttr.cpp
133 ↗(On Diff #7007)

Sure.

rnk updated this revision to Unknown Object (????).Feb 12 2014, 12:39 PM
  • Use an enum in MSVtorDispAttr
majnemer added inline comments.Feb 12 2014, 12:54 PM
include/clang/Driver/CLCompatOptions.td
121 ↗(On Diff #7007)

We still need a test for when -vd1 is specified with -vd2.

lib/Parse/ParsePragma.cpp
192 ↗(On Diff #7007)

I'm not worried about using the allocator for things like this, #pragma vtordisp is very rare.

I don't see a technical argument for duplicating the code to examine "on" and "off".

rnk updated this revision to Unknown Object (????).Feb 12 2014, 2:59 PM
  • Parse integer literals up front, rather than in Parser
majnemer accepted this revision.Feb 12 2014, 3:08 PM

LGTM

lib/Lex/Preprocessor.cpp
832 ↗(On Diff #7035)

Value is 64-bit, shouldn't this be ApVal(32, 0) ?

rnk closed this revision.Feb 12 2014, 3:57 PM

Closed by commit rL201274 (authored by @rnk).