From f8da20716a85dee1d902483f90223a36cef8ba06 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Tue, 28 Oct 2025 13:55:59 +0100 Subject: [PATCH] [Index] Add symbol properties to record the Swift access level of a declaration This will allow us to record the access level of a Swift symbol in the index store. rdar://163256878 --- clang/include/clang/Index/IndexSymbol.h | 44 ++++++++++++++++++------- clang/include/indexstore/indexstore.h | 30 ++++++++++------- clang/lib/Index/IndexDataStoreUtils.cpp | 19 +++++++++++ clang/lib/Index/IndexSymbol.cpp | 25 ++++++++++++++ 4 files changed, 95 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/Index/IndexSymbol.h b/clang/include/clang/Index/IndexSymbol.h index 039434933b2b3..5c6cee6adee99 100644 --- a/clang/include/clang/Index/IndexSymbol.h +++ b/clang/include/clang/Index/IndexSymbol.h @@ -110,21 +110,43 @@ enum class SymbolSubKind : uint8_t { typedef uint32_t SymbolPropertySet; /// Set of properties that provide additional info about a symbol. enum class SymbolProperty : SymbolPropertySet { - Generic = 1 << 0, + Generic = 1 << 0, TemplatePartialSpecialization = 1 << 1, - TemplateSpecialization = 1 << 2, - UnitTest = 1 << 3, - IBAnnotated = 1 << 4, - IBOutletCollection = 1 << 5, - GKInspectable = 1 << 6, - Local = 1 << 7, + TemplateSpecialization = 1 << 2, + UnitTest = 1 << 3, + IBAnnotated = 1 << 4, + IBOutletCollection = 1 << 5, + GKInspectable = 1 << 6, + Local = 1 << 7, /// Symbol is part of a protocol interface. - ProtocolInterface = 1 << 8, - - /// Swift-only properties - SwiftAsync = 1 << 16, + ProtocolInterface = 1 << 8, + + /// --- Swift-only properties + + /// Whether this is a `async` function. + SwiftAsync = 1 << 16, + + /// Swift Access control levels, packed into 3 bits. + /// + /// Use \c applyForEachSymbolProperty or \c + /// getSwiftAccessLevelFromSymbolPropertySet to correctly unpack these from a + /// \c SymbolPropertySet. + SwiftAccessControlLessThanFilePrivate = 1 << 17, + SwiftAccessControlFilePrivate = 1 << 18, + SwiftAccessControlInternal = 1 << 18 | 1 << 17, + SwiftAccessControlPackage = 1 << 19, + SwiftAccessControlSPI = 1 << 19 | 1 << 17, + SwiftAccessControlPublic = 1 << 19 | 1 << 18, }; +/// The Swift access level is bit-packed into `SymbolPropertySet` so we can't +/// easily apply a \c SymbolProperty bit-mask to a \c SymbolPropertySet to check +/// for the access level. This function extracts the access level from a \c +/// SymbolPropertySet. It guarantees to only ever return a \c +/// SwiftAccessControl* case of \c SymbolProperty. +std::optional + getSwiftAccessLevelFromSymbolPropertySet(SymbolPropertySet); + /// Set of roles that are attributed to symbol occurrences. /// /// Low 9 bits of clang-c/include/Index.h CXSymbolRole mirrors this enum. diff --git a/clang/include/indexstore/indexstore.h b/clang/include/indexstore/indexstore.h index 6b000ddfbb7a4..4f4831ee1c693 100644 --- a/clang/include/indexstore/indexstore.h +++ b/clang/include/indexstore/indexstore.h @@ -318,18 +318,24 @@ typedef enum { INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORMUTATE = 1018, } indexstore_symbol_subkind_t; -INDEXSTORE_OPTIONS(uint64_t, indexstore_symbol_property_t) { - INDEXSTORE_SYMBOL_PROPERTY_GENERIC = 1 << 0, - INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_PARTIAL_SPECIALIZATION = 1 << 1, - INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_SPECIALIZATION = 1 << 2, - INDEXSTORE_SYMBOL_PROPERTY_UNITTEST = 1 << 3, - INDEXSTORE_SYMBOL_PROPERTY_IBANNOTATED = 1 << 4, - INDEXSTORE_SYMBOL_PROPERTY_IBOUTLETCOLLECTION = 1 << 5, - INDEXSTORE_SYMBOL_PROPERTY_GKINSPECTABLE = 1 << 6, - INDEXSTORE_SYMBOL_PROPERTY_LOCAL = 1 << 7, - INDEXSTORE_SYMBOL_PROPERTY_PROTOCOL_INTERFACE = 1 << 8, - - INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ASYNC = 1 << 16, +INDEXSTORE_OPTIONS(uint64_t, indexstore_symbol_property_t){ + INDEXSTORE_SYMBOL_PROPERTY_GENERIC = 1 << 0, + INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_PARTIAL_SPECIALIZATION = 1 << 1, + INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_SPECIALIZATION = 1 << 2, + INDEXSTORE_SYMBOL_PROPERTY_UNITTEST = 1 << 3, + INDEXSTORE_SYMBOL_PROPERTY_IBANNOTATED = 1 << 4, + INDEXSTORE_SYMBOL_PROPERTY_IBOUTLETCOLLECTION = 1 << 5, + INDEXSTORE_SYMBOL_PROPERTY_GKINSPECTABLE = 1 << 6, + INDEXSTORE_SYMBOL_PROPERTY_LOCAL = 1 << 7, + INDEXSTORE_SYMBOL_PROPERTY_PROTOCOL_INTERFACE = 1 << 8, + + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ASYNC = 1 << 16, + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_LESSTHANFILEPRIVATE = 1 << 17, + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_FILEPRIVATE = 1 << 18, + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_INTERNAL = 1 << 18 | 1 << 17, + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_PACKAGE = 1 << 19, + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_SPI = 1 << 19 | 1 << 17, + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_PUBLIC = 1 << 19 | 1 << 18, }; typedef enum { diff --git a/clang/lib/Index/IndexDataStoreUtils.cpp b/clang/lib/Index/IndexDataStoreUtils.cpp index 38e8b4970db8d..893773467da11 100644 --- a/clang/lib/Index/IndexDataStoreUtils.cpp +++ b/clang/lib/Index/IndexDataStoreUtils.cpp @@ -483,6 +483,25 @@ indexstore_symbol_property_t index::getIndexStoreProperties(SymbolPropertySet Pr case SymbolProperty::SwiftAsync: storeProp |= INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ASYNC; break; + case SymbolProperty::SwiftAccessControlLessThanFilePrivate: + storeProp |= + INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_LESSTHANFILEPRIVATE; + break; + case SymbolProperty::SwiftAccessControlFilePrivate: + storeProp |= INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_FILEPRIVATE; + break; + case SymbolProperty::SwiftAccessControlInternal: + storeProp |= INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_INTERNAL; + break; + case SymbolProperty::SwiftAccessControlPackage: + storeProp |= INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_PACKAGE; + break; + case SymbolProperty::SwiftAccessControlSPI: + storeProp |= INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_SPI; + break; + case SymbolProperty::SwiftAccessControlPublic: + storeProp |= INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ACCESSCONTROL_PUBLIC; + break; } }); return static_cast(storeProp); diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp index 97bd0f6a017ea..1ed4a04c27a9a 100644 --- a/clang/lib/Index/IndexSymbol.cpp +++ b/clang/lib/Index/IndexSymbol.cpp @@ -587,6 +587,14 @@ StringRef index::getSymbolLanguageString(SymbolLanguage K) { llvm_unreachable("invalid symbol language kind"); } +std::optional +index::getSwiftAccessLevelFromSymbolPropertySet(SymbolPropertySet Props) { + if (uint32_t AccessLevel = Props & (1 << 19 | 1 << 18 | 1 << 17)) { + return (SymbolProperty)AccessLevel; + } + return std::nullopt; +} + void index::applyForEachSymbolProperty(SymbolPropertySet Props, llvm::function_ref Fn) { #define APPLY_FOR_PROPERTY(K) \ @@ -605,6 +613,11 @@ void index::applyForEachSymbolProperty(SymbolPropertySet Props, APPLY_FOR_PROPERTY(SwiftAsync); #undef APPLY_FOR_PROPERTY + + /// Access levels are bit-packed, so we need to handle them explicitly. + if (auto AccessLevel = getSwiftAccessLevelFromSymbolPropertySet(Props)) { + Fn(*AccessLevel); + } } void index::printSymbolProperties(SymbolPropertySet Props, raw_ostream &OS) { @@ -625,6 +638,18 @@ void index::printSymbolProperties(SymbolPropertySet Props, raw_ostream &OS) { case SymbolProperty::Local: OS << "local"; break; case SymbolProperty::ProtocolInterface: OS << "protocol"; break; case SymbolProperty::SwiftAsync: OS << "swift_async"; break; + case SymbolProperty::SwiftAccessControlLessThanFilePrivate: + OS << "less_than_private"; + break; + case SymbolProperty::SwiftAccessControlFilePrivate: OS << "fileprivate"; break; + case SymbolProperty::SwiftAccessControlInternal: OS << "internal"; break; + case SymbolProperty::SwiftAccessControlPackage: OS << "package"; break; + case SymbolProperty::SwiftAccessControlSPI: + OS << "SPI"; + break; + case SymbolProperty::SwiftAccessControlPublic: + OS << "public"; + break; } }); }