Skip to content

Commit 3f44e19

Browse files
committed
[APINotes] Handle global variables in namespaces
rdar://113403829
1 parent 523e9e9 commit 3f44e19

File tree

9 files changed

+70
-16
lines changed

9 files changed

+70
-16
lines changed

clang/include/clang/APINotes/APINotesReader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ class APINotesReader {
175175
/// \param name The name of the global variable.
176176
///
177177
/// \returns information about the global variable, if known.
178-
VersionedInfo<GlobalVariableInfo> lookupGlobalVariable(llvm::StringRef name);
178+
VersionedInfo<GlobalVariableInfo>
179+
lookupGlobalVariable(std::optional<Context> context, llvm::StringRef name);
179180

180181
/// Look for information regarding the given global function.
181182
///

clang/include/clang/APINotes/APINotesWriter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ class APINotesWriter {
8585
///
8686
/// \param name The name of this global variable.
8787
/// \param info Information about this global variable.
88-
void addGlobalVariable(llvm::StringRef name, const GlobalVariableInfo &info,
88+
void addGlobalVariable(std::optional<Context> context, llvm::StringRef name,
89+
const GlobalVariableInfo &info,
8990
llvm::VersionTuple swiftVersion);
9091

9192
/// Add information about a global function.

clang/lib/APINotes/APINotesReader.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,15 @@ namespace {
432432

433433
/// Used to deserialize the on-disk global variable table.
434434
class GlobalVariableTableInfo
435-
: public VersionedTableInfo<GlobalVariableTableInfo, unsigned,
436-
GlobalVariableInfo> {
435+
: public VersionedTableInfo<GlobalVariableTableInfo,
436+
std::tuple<uint32_t, uint8_t, uint32_t>,
437+
GlobalVariableInfo> {
437438
public:
438439
static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
440+
auto contextID = endian::readNext<uint32_t, little, unaligned>(data);
441+
auto contextKind = endian::readNext<uint8_t, little, unaligned>(data);
439442
auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
440-
return nameID;
443+
return {contextID, contextKind, nameID};
441444
}
442445

443446
static GlobalVariableInfo readUnversioned(internal_key_type key,
@@ -1936,7 +1939,7 @@ auto APINotesReader::lookupObjCMethod(
19361939
return { Impl.SwiftVersion, *known };
19371940
}
19381941

1939-
auto APINotesReader::lookupGlobalVariable(
1942+
auto APINotesReader::lookupGlobalVariable(std::optional<Context> context,
19401943
StringRef name)
19411944
-> VersionedInfo<GlobalVariableInfo> {
19421945
if (!Impl.GlobalVariableTable)
@@ -1946,7 +1949,13 @@ auto APINotesReader::lookupGlobalVariable(
19461949
if (!nameID)
19471950
return None;
19481951

1949-
auto known = Impl.GlobalVariableTable->find(*nameID);
1952+
std::tuple<uint32_t, uint8_t, uint32_t> key;
1953+
if (context)
1954+
key = {context->id.Value, (uint8_t)context->kind, *nameID};
1955+
else
1956+
key = {-1, (uint8_t)-1, *nameID};
1957+
1958+
auto known = Impl.GlobalVariableTable->find(key);
19501959
if (known == Impl.GlobalVariableTable->end())
19511960
return None;
19521961

clang/lib/APINotes/APINotesWriter.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ class APINotesWriter::Implementation {
9393

9494
/// Information about global variables.
9595
///
96-
/// Indexed by the identifier ID.
97-
llvm::DenseMap<unsigned,
96+
/// Indexed by the context ID, contextKind, identifier ID.
97+
llvm::DenseMap<std::tuple<uint32_t, uint8_t, uint32_t>,
9898
llvm::SmallVector<std::pair<VersionTuple, GlobalVariableInfo>,
9999
1>>
100100
GlobalVariables;
@@ -906,16 +906,18 @@ namespace {
906906
/// Used to serialize the on-disk global variable table.
907907
class GlobalVariableTableInfo
908908
: public VersionedTableInfo<GlobalVariableTableInfo,
909-
unsigned,
909+
std::tuple<uint32_t, uint8_t, uint32_t>,
910910
GlobalVariableInfo> {
911911
public:
912912
unsigned getKeyLength(key_type_ref key) {
913-
return sizeof(uint32_t);
913+
return sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t);
914914
}
915915

916916
void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
917917
endian::Writer writer(out, little);
918-
writer.write<uint32_t>(key);
918+
writer.write<uint32_t>(std::get<0>(key));
919+
writer.write<uint8_t>(std::get<1>(key));
920+
writer.write<uint32_t>(std::get<2>(key));
919921
}
920922

921923
unsigned getUnversionedInfoSize(const GlobalVariableInfo &info) {
@@ -1321,11 +1323,17 @@ void APINotesWriter::addObjCMethod(ContextID contextID,
13211323
}
13221324
}
13231325

1324-
void APINotesWriter::addGlobalVariable(llvm::StringRef name,
1326+
void APINotesWriter::addGlobalVariable(std::optional<Context> context,
1327+
llvm::StringRef name,
13251328
const GlobalVariableInfo &info,
13261329
VersionTuple swiftVersion) {
13271330
IdentifierID variableID = Impl.getIdentifier(name);
1328-
Impl.GlobalVariables[variableID].push_back({swiftVersion, info});
1331+
std::tuple<uint32_t, uint8_t, uint32_t> key;
1332+
if (context)
1333+
key = {context->id.Value, (uint8_t)context->kind, variableID};
1334+
else
1335+
key = {-1, (uint8_t)-1, variableID};
1336+
Impl.GlobalVariables[key].push_back({swiftVersion, info});
13291337
}
13301338

13311339
void APINotesWriter::addGlobalFunction(std::optional<Context> context,

clang/lib/APINotes/APINotesYAMLCompiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ namespace {
10741074
if (global.Nullability)
10751075
info.setNullabilityAudited(*global.Nullability);
10761076
info.setType(std::string(global.Type));
1077-
Writer->addGlobalVariable(global.Name, info, swiftVersion);
1077+
Writer->addGlobalVariable(context, global.Name, info, swiftVersion);
10781078
}
10791079

10801080
// Write all global functions.

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,8 @@ void Sema::ProcessAPINotes(Decl *D) {
847847
// Global variables.
848848
if (auto VD = dyn_cast<VarDecl>(D)) {
849849
for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
850-
auto Info = Reader->lookupGlobalVariable(VD->getName());
850+
auto Info =
851+
Reader->lookupGlobalVariable(APINotesContext, VD->getName());
851852
ProcessVersionedAPINotes(*this, VD, Info);
852853
}
853854

clang/test/APINotes/Inputs/Frameworks/CXXInteropKit.framework/Headers/CXXInteropKit.apinotes

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Tags:
2020
SwiftName: InWrongContext
2121
Namespaces:
2222
- Name: Namespace1
23+
Globals:
24+
- Name: varInNamespace
25+
SwiftName: swiftVarInNamespace
2326
Functions:
2427
- Name: funcInNamespace
2528
SwiftName: swiftFuncInNamespace()
@@ -28,6 +31,9 @@ Namespaces:
2831
SwiftName: CharBox
2932
Namespaces:
3033
- Name: Nested1
34+
Globals:
35+
- Name: varInNestedNamespace
36+
SwiftName: swiftVarInNestedNamespace
3137
Functions:
3238
- Name: funcInNestedNamespace
3339
SwiftName: swiftFuncInNestedNamespace(_:)
@@ -39,3 +45,7 @@ Namespaces:
3945
Tags:
4046
- Name: char_box
4147
SwiftName: DeepNestedCharBox
48+
- Name: Nested2
49+
Globals:
50+
- Name: varInNestedNamespace
51+
SwiftName: swiftAnotherVarInNestedNamespace

clang/test/APINotes/Inputs/Frameworks/CXXInteropKit.framework/Headers/CXXInteropKit.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef NS_OPTIONS(NSUInteger, NSSomeEnumOptions) {
2525
namespace Namespace1 { namespace Nested1 {} }
2626

2727
namespace Namespace1 {
28+
static int varInNamespace = 1;
2829
struct char_box { char c; };
2930
void funcInNamespace();
3031

@@ -34,13 +35,18 @@ struct char_box { char c; };
3435
}
3536

3637
namespace Nested1 {
38+
static int varInNestedNamespace = 1;
3739
void funcInNestedNamespace(int i);
3840

3941
namespace Namespace1 {
4042
struct char_box { char c; };
4143
} // namespace Namespace1
4244
} // namespace Nested1
4345

46+
namespace Nested2 {
47+
static int varInNestedNamespace = 2;
48+
} // namespace Nested2
49+
4450
namespace Nested1 { namespace Namespace1 {} }
4551
} // namespace Namespace1
4652

clang/test/APINotes/objcxx-swift-name.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -x objective-c++
33
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter SomeClass -x objective-c++ | FileCheck %s
44
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter "(anonymous)" -x objective-c++ | FileCheck -check-prefix=CHECK-ANONYMOUS-ENUM %s
5+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::varInNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-GLOBAL-IN-NAMESPACE %s
56
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::funcInNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-FUNC-IN-NAMESPACE %s
67
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-NAMESPACE %s
8+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::varInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-GLOBAL-IN-NESTED-NAMESPACE %s
9+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested2::varInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE %s
710
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-NESTED-NAMESPACE %s
811
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::funcInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-FUNC-IN-NESTED-NAMESPACE %s
912
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::Namespace1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE %s
@@ -27,6 +30,11 @@
2730
// CHECK-ANONYMOUS-ENUM-NEXT: EnumDecl {{.+}} imported in CXXInteropKit <undeserialized declarations> 'NSSomeEnumOptions':'unsigned long'
2831
// CHECK-ANONYMOUS-ENUM-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "SomeEnum.Options"
2932

33+
// CHECK-GLOBAL-IN-NAMESPACE: Dumping Namespace1::varInNamespace:
34+
// CHECK-GLOBAL-IN-NAMESPACE-NEXT: VarDecl {{.+}} imported in CXXInteropKit varInNamespace 'int' static cinit
35+
// CHECK-GLOBAL-IN-NAMESPACE-NEXT: IntegerLiteral {{.+}} 'int' 1
36+
// CHECK-GLOBAL-IN-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftVarInNamespace"
37+
3038
// CHECK-FUNC-IN-NAMESPACE: Dumping Namespace1::funcInNamespace:
3139
// CHECK-FUNC-IN-NAMESPACE-NEXT: FunctionDecl {{.+}} imported in CXXInteropKit funcInNamespace 'void ()'
3240
// CHECK-FUNC-IN-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftFuncInNamespace()"
@@ -35,6 +43,16 @@
3543
// CHECK-STRUCT-IN-NAMESPACE-NEXT: CXXRecordDecl {{.+}} imported in CXXInteropKit <undeserialized declarations> struct char_box
3644
// CHECK-STRUCT-IN-NAMESPACE: SwiftNameAttr {{.+}} <<invalid sloc>> "CharBox"
3745

46+
// CHECK-GLOBAL-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested1::varInNestedNamespace:
47+
// CHECK-GLOBAL-IN-NESTED-NAMESPACE-NEXT: VarDecl {{.+}} imported in CXXInteropKit varInNestedNamespace 'int' static cinit
48+
// CHECK-GLOBAL-IN-NESTED-NAMESPACE-NEXT: IntegerLiteral {{.+}} 'int' 1
49+
// CHECK-GLOBAL-IN-NESTED-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftVarInNestedNamespace"
50+
51+
// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested2::varInNestedNamespace:
52+
// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE-NEXT: VarDecl {{.+}} imported in CXXInteropKit varInNestedNamespace 'int' static cinit
53+
// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE-NEXT: IntegerLiteral {{.+}} 'int' 2
54+
// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftAnotherVarInNestedNamespace"
55+
3856
// CHECK-FUNC-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested1::funcInNestedNamespace:
3957
// CHECK-FUNC-IN-NESTED-NAMESPACE-NEXT: FunctionDecl {{.+}} imported in CXXInteropKit funcInNestedNamespace 'void (int)'
4058
// CHECK-FUNC-IN-NESTED-NAMESPACE-NEXT: ParmVarDecl {{.+}} i 'int'

0 commit comments

Comments
 (0)