Author: Gábor Horváth Date: 2026-01-20T10:05:02Z New Revision: 2428a684978e5816c3a83c55a1395e4fe8cfe50e
URL: https://github.com/llvm/llvm-project/commit/2428a684978e5816c3a83c55a1395e4fe8cfe50e DIFF: https://github.com/llvm/llvm-project/commit/2428a684978e5816c3a83c55a1395e4fe8cfe50e.diff LOG: [APINotes] Apply APINotes to non-global decls in a LinkageSpecDecl (#176792) We checked if a declaration has a LinkageSpecDecl ancestor and assumed that it would be a declaration in global/namespace scope. This prevented us from applying APINotes to methods or fields of a class that was declared in a LinkageSpecDecl. This PR changes the logic to only check whether the parent DeclContext is a LinkageSpecDecl instead of checking for all the ancestors. Co-authored-by: Gabor Horvath <[email protected]> Added: Modified: clang/lib/Sema/SemaAPINotes.cpp clang/test/APINotes/Inputs/Headers/Methods.apinotes clang/test/APINotes/Inputs/Headers/Methods.h clang/test/APINotes/methods.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index 0d8d0faa59abd..d041d0f1f0a30 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -987,8 +987,8 @@ void Sema::ProcessAPINotes(Decl *D) { auto *DC = D->getDeclContext(); // Globals. - if (DC->isFileContext() || DC->isNamespace() || DC->isExternCContext() || - DC->isExternCXXContext()) { + if (DC->isFileContext() || DC->isNamespace() || + DC->getDeclKind() == Decl::LinkageSpec) { std::optional<api_notes::Context> APINotesContext = UnwindNamespaceContext(DC, APINotes); // Global variables. diff --git a/clang/test/APINotes/Inputs/Headers/Methods.apinotes b/clang/test/APINotes/Inputs/Headers/Methods.apinotes index 618c2cb14b47f..98fb7c5a489cb 100644 --- a/clang/test/APINotes/Inputs/Headers/Methods.apinotes +++ b/clang/test/APINotes/Inputs/Headers/Methods.apinotes @@ -9,6 +9,16 @@ Tags: - Name: getDecremented Availability: none AvailabilityMsg: "this should have no effect" +- Name: IntWrapper2 + Methods: + - Name: getIncremented + Availability: none + AvailabilityMsg: "oh no" +- Name: IntWrapper3 + Methods: + - Name: getIncremented + Availability: none + AvailabilityMsg: "oh no" - Name: Outer Tags: - Name: Inner diff --git a/clang/test/APINotes/Inputs/Headers/Methods.h b/clang/test/APINotes/Inputs/Headers/Methods.h index cbb57ccd0afbd..f4eb3589429d3 100644 --- a/clang/test/APINotes/Inputs/Headers/Methods.h +++ b/clang/test/APINotes/Inputs/Headers/Methods.h @@ -6,6 +6,22 @@ struct IntWrapper { IntWrapper operator+(const IntWrapper& RHS) const { return {value + RHS.value}; } }; +extern "C++" { +struct IntWrapper2 { + int value; + + IntWrapper2 getIncremented() const { return {value + 1}; } +}; +} + +extern "C++" { +extern "C" { + struct IntWrapper3 { + static IntWrapper3 getIncremented(IntWrapper3 val) { return val; } + }; +} +} + struct Outer { struct Inner { int value; diff --git a/clang/test/APINotes/methods.cpp b/clang/test/APINotes/methods.cpp index 910565745bea2..a38642604a175 100644 --- a/clang/test/APINotes/methods.cpp +++ b/clang/test/APINotes/methods.cpp @@ -1,6 +1,8 @@ // RUN: rm -rf %t && mkdir -p %t // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -x c++ // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter IntWrapper::getIncremented -x c++ | FileCheck --check-prefix=CHECK-METHOD %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter IntWrapper2::getIncremented -x c++ | FileCheck --check-prefix=CHECK-METHOD-2 %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter IntWrapper3::getIncremented -x c++ | FileCheck --check-prefix=CHECK-METHOD-3 %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Methods -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Outer::Inner::getDecremented -x c++ | FileCheck --check-prefix=CHECK-DEEP-METHOD %s #include "Methods.h" @@ -9,6 +11,14 @@ // CHECK-METHOD-NEXT: CXXMethodDecl {{.+}} getIncremented // CHECK-METHOD: UnavailableAttr {{.+}} <<invalid sloc>> "oh no" +// CHECK-METHOD-2: Dumping IntWrapper2::getIncremented: +// CHECK-METHOD-2-NEXT: CXXMethodDecl {{.+}} getIncremented +// CHECK-METHOD-2: UnavailableAttr {{.+}} <<invalid sloc>> "oh no" + +// CHECK-METHOD-3: Dumping IntWrapper3::getIncremented: +// CHECK-METHOD-3-NEXT: CXXMethodDecl {{.+}} getIncremented +// CHECK-METHOD-3: UnavailableAttr {{.+}} <<invalid sloc>> "oh no" + // CHECK-DEEP-METHOD: Dumping Outer::Inner::getDecremented: // CHECK-DEEP-METHOD-NEXT: CXXMethodDecl {{.+}} getDecremented // CHECK-DEEP-METHOD: UnavailableAttr {{.+}} <<invalid sloc>> "nope" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
