Skip to content

[API Notes] Allow tag-based API notes on anonymous tag decls with typedef names #7871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion clang/lib/Sema/SemaAPINotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,15 @@ void Sema::ProcessAPINotes(Decl *D) {

// Tags
if (auto Tag = dyn_cast<TagDecl>(D)) {
std::string LookupName = Tag->getName().str();
// Determine the name of the entity to search for. If this is an
// anonymous tag that gets its linked name from a typedef, look for the
// typedef name. This allows tag-specific information to be added
// to the declaration.
std::string LookupName;
if (auto typedefName = Tag->getTypedefNameForAnonDecl())
LookupName = typedefName->getName().str();
else
LookupName = Tag->getName().str();

// Use the source location to discern if this Tag is an OPTIONS macro.
// For now we would like to limit this trick of looking up the APINote tag
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5041,6 +5041,9 @@ void Sema::setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec,

// Otherwise, set this as the anon-decl typedef for the tag.
TagFromDeclSpec->setTypedefNameForAnonDecl(NewTD);

// Now that we have a name for the tag, process API notes again.
ProcessAPINotes(TagFromDeclSpec);
}

static unsigned GetDiagnosticTypeSpecifierID(const DeclSpec &DS) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ Tags:
SwiftName: SuccessfullyRenamedA
- Name: RenamedAgainInAPINotesB
SwiftName: SuccessfullyRenamedB
- Name: AnonEnumWithTypedefName
SwiftName: SuccessfullyRenamedC
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ void *getCFAuditedToNone_DUMP(void);
- (id)getOwnedToUnowned __attribute__((__ns_returns_retained__));
- (id)getUnownedToOwned __attribute__((__ns_returns_not_retained__));
@end

typedef enum {
kConstantInAnonEnum
} AnonEnumWithTypedefName;
3 changes: 3 additions & 0 deletions clang/test/APINotes/types.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

// CHECK: struct __attribute__((swift_name("SuccessfullyRenamedA"))) RenamedAgainInAPINotesA {
// CHECK: struct __attribute__((swift_name("SuccessfullyRenamedB"))) RenamedAgainInAPINotesB {
// CHECK: typedef enum __attribute__((swift_name("SuccessfullyRenamedC"))) {
// CHECK-NEXT: kConstantInAnonEnum
// CHECK-NEXT: } AnonEnumWithTypedefName

void test(OverriddenTypes *overridden) {
int *ip1 = global_int_ptr; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'double (*)(int, int)'}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/APINotes/yaml-roundtrip-2.test
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ REQUIRES: shell

We expect only the document markers to be emitted

CHECK: 50d
CHECK: 52d
CHECK: 1d