This is an archive of the discontinued LLVM Phabricator instance.

Convert a few classes over to use the new TrailingObjects helper.
ClosedPublic

Authored by jyknight on Jul 17 2015, 7:48 AM.

Details

Summary

This initial commit serves as an example -- the remainder of the
classes using pointer arithmetic for trailing objects will be
converted in subsequent changes.

Diff Detail

Repository
rL LLVM

Event Timeline

jyknight updated this revision to Diff 30002.Jul 17 2015, 7:48 AM
jyknight retitled this revision from to Convert a few classes over to use the new TrailingObjects helper..
jyknight updated this object.
jyknight added reviewers: bogner, majnemer, rsmith, rnk.
jyknight added subscribers: rengolin, rnk, majnemer, cfe-commits.
jyknight updated this revision to Diff 30010.Jul 17 2015, 9:23 AM

Fix after changes in D11272.

rnk edited edge metadata.Aug 3 2015, 9:55 AM

I'd rather hold of on stamping this and let Richard look at it, since it changes AST pretty heavily.

include/clang/AST/DeclTemplate.h
146 ↗(On Diff #30010)

Won't this reduce the alignment of this structure to 1?

rsmith added inline comments.Aug 3 2015, 1:17 PM
include/clang/AST/Decl.h
3620 ↗(On Diff #30010)

I would prefer to see an explicit private access specifier here.

3638–3642 ↗(On Diff #30010)

The uses of this below appear to be const-correct; maybe add const and non-const overloads without the const_cast?

3702 ↗(On Diff #30010)

I predict one of our supported host compilers will choke on this.

*experiments*

That compiler is MSVC. It appears all our supported compilers provide enough C++11 to allow

friend TrailingObjects;
include/clang/AST/DeclTemplate.h
47 ↗(On Diff #30010)

Can you remove the LLVM_ALIGNAS?

145 ↗(On Diff #30010)

This type is now underaligned.

146 ↗(On Diff #30010)

Do all of our supported compilers provide enough constexpr support for this to actually work? How would you feel about:

TemplateParameterList List;
NamedDecl *Params[N];

(Yeah, I don't like this either.)

165 ↗(On Diff #30010)

Please check in the removal of the Owned flag separately.

1290–1302 ↗(On Diff #30010)

Wow, this is still pretty gross. Can we use std::pair<QualType, TypeSourceInfo*> as the trailing object type, or something morally equivalent?

lib/AST/Decl.cpp
3129 ↗(On Diff #30010)

Why do you need to specify the types here? Shouldn't they be implied by the type of the TrailingObjects base class?

3896 ↗(On Diff #30010)

Likewise here.

jyknight marked an inline comment as done.Aug 5 2015, 10:08 AM
jyknight added inline comments.
include/clang/AST/Decl.h
3620 ↗(On Diff #30010)

Done here and everywhere.

3702 ↗(On Diff #30010)

Done here and everywhere

include/clang/AST/DeclTemplate.h
47 ↗(On Diff #30010)

Nope, still needs to be provded manually. The TrailingObjects class does not currently adjust the alignment for you, but rather, just static_asserts that you've gotten it right. I'd like it to, but right now, the argument to LLVM_ALIGNAS apparently needs to be a literal integer for MSVC.

...although...actually, now that I think about it more, it may actually be possible to make it work even on VC. I don't have a way to test it, but I think something like the following might do the trick.

I'd like to avoid trying to add this feature to the llvm TrailingObjects class right now, though, and try it in a follow-up later on, OK?

template<int Align> class AlignmentHelper {};

template<> class LLVM_ALIGNAS(1) AlignmentHelper<1> {};
template<> class LLVM_ALIGNAS(2) AlignmentHelper<2> {};
template<> class LLVM_ALIGNAS(4) AlignmentHelper<4> {};
template<> class LLVM_ALIGNAS(8) AlignmentHelper<8> {};
template<> class LLVM_ALIGNAS(16) AlignmentHelper<16> {};
template<> class LLVM_ALIGNAS(32) AlignmentHelper<32> {};

class OtherThing {
  double x;
};

class SomeThing : AlignmentHelper<AlignOf<OtherThing>::Alignment> {
  char x;
};

int main() {
  static_assert(AlignOf<OtherThing>::Alignment == AlignOf<SomeThing>::Alignment, "");
}
145 ↗(On Diff #30010)

Indeed! stupid oversight from adjusting the code at the last minute for the required "final". Should've inserted an alignment here too. But because of the constexpr issue, this goes away anyways...

146 ↗(On Diff #30010)

Yeah, right, no constexpr in VS2013. So, I guess that'll have to do...yuck but oh well.

I stuck in some asserts for the layout being as expected to assuage my conscience.

165 ↗(On Diff #30010)

Acknowledged. [but still in this change as of right now]

1290–1302 ↗(On Diff #30010)

Done (could also use two trailing arrays, of QualType and separately of TypeSourceInfo*, but this is closer to the current code)

lib/AST/Decl.cpp
3129 ↗(On Diff #30010)

I made the API require them, because I didn't like the interface with the unadorned integers in an arbitrary order. It just seemed too easy to forget to update these, if you swapped the order of the types in the class, e.g. for alignment reasons.

So, {additional,total}SizeToAlloc requires the types be presented here, redundantly.

jyknight updated this revision to Diff 31366.Aug 5 2015, 10:08 AM
jyknight edited edge metadata.

Review comments

rsmith accepted this revision.Aug 5 2015, 2:14 PM
rsmith edited edge metadata.

Looks like a really nice cleanup, thanks!

include/clang/AST/DeclTemplate.h
47–49 ↗(On Diff #31366)

I've used that trick in the past to work around the same bug in older versions of GCC; I think it should work OK (but we're getting into known-weird corners of MSVC record layout). Doing that in a follow-up change seems fine to me.

lib/AST/Decl.cpp
3122 ↗(On Diff #31366)

OK, I guessed that might be the reason. Seems like a reasonable safety measure. (Do you get an error if you specify the wrong types?)

lib/AST/DeclTemplate.cpp
554–557 ↗(On Diff #31366)

I'd prefer a placement new expression here rather than calling the assignment operator on an uninitialized QualType object.

This revision is now accepted and ready to land.Aug 5 2015, 2:14 PM
This revision was automatically updated to reflect the committed changes.
jyknight marked 2 inline comments as done.Aug 6 2015, 1:30 PM
jyknight added inline comments.
lib/AST/Decl.cpp
3122 ↗(On Diff #31366)

Yep, the function has an enable_if to ensure you call it with the right types.