Author: Doug Gregor Date: 2024-10-02T18:21:23+01:00 New Revision: 694fd1f297feaf59cd29a3d17e63ee2f6514dd16
URL: https://github.com/llvm/llvm-project/commit/694fd1f297feaf59cd29a3d17e63ee2f6514dd16 DIFF: https://github.com/llvm/llvm-project/commit/694fd1f297feaf59cd29a3d17e63ee2f6514dd16.diff LOG: Allow tag-based API notes on anonymous tag decls with typedef names It is common practice in C to declare anonymous tags that are immediately given a typedef name, e.g., typedef enum { ... } MyType; At present, one can only express API notes on the typedef. However, that excludes the possibility of tag-specific notes like EnumExtensibility. For these anonymous declarations, process API notes using the typedef name as the tag name, so that one can add API notes to `MyType` via the `Tags` section. Added: Modified: clang/lib/Sema/SemaAPINotes.cpp clang/lib/Sema/SemaDecl.cpp clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h clang/test/APINotes/types.m clang/test/APINotes/yaml-roundtrip-2.test Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index d0236d08c98e68..ec43a0def9c1e6 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -913,7 +913,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 diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e4c45cbc09e0f7..add28b370bcfcc 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4974,6 +4974,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) { diff --git a/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes b/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes index ef6e44c51c21c7..f51811354eb00b 100644 --- a/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes +++ b/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes @@ -46,3 +46,5 @@ Tags: SwiftName: SuccessfullyRenamedA - Name: RenamedAgainInAPINotesB SwiftName: SuccessfullyRenamedB + - Name: AnonEnumWithTypedefName + SwiftName: SuccessfullyRenamedC diff --git a/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h b/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h index bd73926e9d6af4..7342c3f83141bb 100644 --- a/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h +++ b/clang/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h @@ -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; diff --git a/clang/test/APINotes/types.m b/clang/test/APINotes/types.m index 133d504713d76c..752f1026432844 100644 --- a/clang/test/APINotes/types.m +++ b/clang/test/APINotes/types.m @@ -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)'}} diff --git a/clang/test/APINotes/yaml-roundtrip-2.test b/clang/test/APINotes/yaml-roundtrip-2.test index b0b777b595060d..63717bda7c0991 100644 --- a/clang/test/APINotes/yaml-roundtrip-2.test +++ b/clang/test/APINotes/yaml-roundtrip-2.test @@ -7,5 +7,5 @@ REQUIRES: shell We expect only the document markers to be emitted -CHECK: 50d +CHECK: 52d CHECK: 1d _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits