Add support for __declspec(code_seg("segname"))
ClosedPublic

Authored by Manna on Feb 15 2018, 1:55 PM.

Details

Summary

Add support for __declspec(code_seg("segname"))

This patch is built on the existing support for #pragma code_seg. The code_seg declspec is allowed on functions and classes. The attribute enables the placement of code into separate named segments, including compiler-generated members and template instantiations.

For more information, please see the following:
https://msdn.microsoft.com/en-us/library/dn636922.aspx

A new CodeSeg attribute is used instead of adding a new spelling to the existing Section attribute since they don’t apply to the same Subjects. Section attributes are also added for the code_seg declspec since they are used for #pragma code_seg. No CodeSeg attributes are added to the AST.

The patch is written to match with the Microsoft compiler’s behavior even where that behavior is a little complicated (see https://reviews.llvm.org/D22931, the Microsoft feedback page is no longer available since MS has removed the page). That code is in getImplicitSectionAttrFromClass routine.

Diagnostics messages are added to match with the Microsoft compiler for code-seg attribute mismatches on base and derived classes and virtual overrides.

Diff Detail

Repository
rC Clang
Manna created this revision.Feb 15 2018, 1:55 PM
rnk added a comment.Feb 15 2018, 3:19 PM

Thanks!

Can you add a test for special member functions? I wasn't able to find one, but maybe there is one already. I tried this and it looks like MSVC uses the class code_seg:

struct NonTrivialCopy {
  NonTrivialCopy();
  NonTrivialCopy(const NonTrivialCopy &);
  ~NonTrivialCopy();
  void *p;
};
struct __declspec(code_seg("asdf")) Foo {
  NonTrivialCopy f1;
};
Foo copy_foo(const Foo &f) {
  return f;
}
test/CodeGenCXX/code_seg3.cpp
4–6 ↗(On Diff #134501)

There's some encoding confusion here, the em-dash seems to have been re-encoded as a smart quote.

aaron.ballman added inline comments.Feb 16 2018, 7:01 AM
include/clang/Basic/Attr.td
1775

Does code_seg work with structures in C as well, or is only used in C++? If it works in C, you should change CXXRecord to be Record and add some C test cases.

include/clang/Basic/DiagnosticSemaKinds.td
2672

I think this should be "derived class must specify the same code segment as its base classes"

I'd like to see test cases where multiple inheritance is involved and the code segments all agree, all disagree, and partially agree between the bases and the derived class. Also, does virtual inheritance change any of the rules?

2674

Similar here: "overriding virtual function must specify the same code segment as its overridden function"

I assume that *overloads* can be in different code segments? Should have test coverage for that.

include/clang/Sema/Sema.h
1937

The FunctionDecl * can be const.

5840

An extra space snuck in here.

lib/Sema/SemaDecl.cpp
2671

const auto *

8727

Please don't use auto here as the type is not explicitly spelled out in the initialization.

8730

SAttr will never be anything but SectionAttr, so you should use cast<> here instead.

9195

const FunctionDecl *

9196

const auto *.

9200

const auto *.

9201

Attr * instead of auto *.

9212

const auto *

9213

Attr *

9232

Spurious newline

lib/Sema/SemaDeclAttr.cpp
2858

const auto *

2952

Attr -> AL (or anything else that doesn't conflict with a type name).

2961–2964

I'd knock this down into a one-liner: S.Diag(Attr.getLoc(), ExistingAttr->getName() == Str ? diag::warn_ : diag::err_);

lib/Sema/SemaDeclCXX.cpp
2237–2238

const auto *

2243

You can just pass in CXXBaseDecl directly -- the diagnostics engine will handle properly quoting everything for you.

14560–14561

const auto *.

lib/Sema/SemaLambda.cpp
913

Don't use auto here.

Manna updated this revision to Diff 145613.May 7 2018, 6:42 PM

New Lit tests are added and patches are updated based on Feedbacks.

Manna marked 15 inline comments as done.May 7 2018, 7:08 PM
Manna marked 7 inline comments as done.May 7 2018, 7:42 PM

There is a test (CodeGenCXX/code_seg1.cpp) for special member functions. I have updated code_seg1.cpp so the test has struct NonTrivialCopy. Could you let me know if it is sufficient?

In D43352#1009418, @rnk wrote:

Thanks!

Can you add a test for special member functions? I wasn't able to find one, but maybe there is one already. I tried this and it looks like MSVC uses the class code_seg:

struct NonTrivialCopy {
  NonTrivialCopy();
  NonTrivialCopy(const NonTrivialCopy &);
  ~NonTrivialCopy();
  void *p;
};
struct __declspec(code_seg("asdf")) Foo {
  NonTrivialCopy f1;
};
Foo copy_foo(const Foo &f) {
  return f;
}
Manna marked an inline comment as done.May 7 2018, 8:15 PM
Manna added inline comments.
include/clang/Basic/Attr.td
1775

__declspec(code_seg(...)) can only be applied to a class or a function.
Code_seg doesn't work with structures in C. We cannot define a function within a struct in C program.

include/clang/Basic/DiagnosticSemaKinds.td
2672

Lit test SemaCXX/code_seg1.cpp is added to show the test cases where multiple inheritance is involved and the code segments all agree, all disagree, and partially disagree between the bases and the derived.

Virtual inheritance doesn't change any rule. It follows the same rule. Lit test SemaCXX/code_seg1.cpp also shows the test cases where virtual inheritance is involved and the code segments all agree, all disagree, and partially disagree between the bases and the derived.

2674

Lit test CodeGenCXX/code_seg4.cpp is added for function overloading.

test/CodeGenCXX/code_seg3.cpp
4–6 ↗(On Diff #134501)

The encoding is fixed.

rnk resigned from this revision.May 10 2018, 2:54 PM

Thanks, this is pretty exhaustive testing. I'll let @aaron.ballman finish off the review. He identified a fair number of style issues.

lib/Sema/SemaDeclAttr.cpp
2950–2972

Keep a blank line here.

aaron.ballman added inline comments.May 11 2018, 10:29 AM
lib/Sema/SemaDeclAttr.cpp
2951

Please do not name the last parameter Attr as that's the name of a type. Other places use AL.

2967

You should not pass in 0 as the last argument, but instead pass the result from a call to getAttributeSpellingListIndex().

lib/Sema/SemaDeclCXX.cpp
2242–2243

This formatting looks off to me, did clang-format produce it?

5598

Don't use auto here as the type's not spelled out.

14565

This return statement seems a bit strange to me -- shouldn't that be return true; after the second call to Diag()?

Manna updated this revision to Diff 146894.May 15 2018, 11:44 AM
Manna marked an inline comment as done.
Manna removed a reviewer: rnk.
Manna updated this revision to Diff 146898.May 15 2018, 12:21 PM
Manna marked 5 inline comments as done.
Manna marked an inline comment as done.May 15 2018, 12:35 PM
Manna added inline comments.
lib/Sema/SemaDeclCXX.cpp
2242–2243

Updated patch is submitted based on your comments.

I have fixed this format issue with the new uploaded patch.

Thanks.

aaron.ballman accepted this revision.May 16 2018, 6:07 AM

Aside from a minor formatting nit, LGTM!

lib/Sema/SemaDeclAttr.cpp
2951

Add a preceding newline.

This revision is now accepted and ready to land.May 16 2018, 6:07 AM
Manna updated this revision to Diff 147075.May 16 2018, 6:49 AM
Manna marked an inline comment as done.

Thanks!

I have fixed the formatting issue with this uploaded patches.

Manna marked an inline comment as done.May 16 2018, 6:51 AM
Manna added inline comments.
lib/Sema/SemaDeclAttr.cpp
2951

Preceding newline is added.

This revision was automatically updated to reflect the committed changes.

Woops, forgot the tests when commiting, so see R332492 for the lit tests.