1 //===-- RecordTests.cpp - TextAPI Record Type Test-------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===-----------------------------------------------------------------------===//
9 #include "llvm/TargetParser/Triple.h"
10 #include "llvm/TextAPI/RecordsSlice.h"
11 #include "gtest/gtest.h"
14 using namespace llvm::MachO
;
16 namespace TAPIRecord
{
18 TEST(TAPIRecord
, Simple
) {
19 GlobalRecord API
{"_sym", RecordLinkage::Rexported
,
20 SymbolFlags::Rexported
| SymbolFlags::Text
|
21 SymbolFlags::ThreadLocalValue
,
22 GlobalRecord::Kind::Function
, /*Inlined=*/false};
23 EXPECT_TRUE(API
.isExported());
24 EXPECT_TRUE(API
.isText());
25 EXPECT_TRUE(API
.isRexported());
26 EXPECT_TRUE(API
.isFunction());
27 EXPECT_TRUE(API
.isThreadLocalValue());
28 EXPECT_FALSE(API
.isInternal());
29 EXPECT_FALSE(API
.isUndefined());
30 EXPECT_FALSE(API
.isWeakDefined());
31 EXPECT_FALSE(API
.isWeakReferenced());
32 EXPECT_FALSE(API
.isVariable());
33 EXPECT_FALSE(API
.isInlined());
36 TEST(TAPIRecord
, SimpleObjC
) {
37 const ObjCIFSymbolKind CompleteInterface
=
38 ObjCIFSymbolKind::Class
| ObjCIFSymbolKind::MetaClass
;
39 ObjCInterfaceRecord Class
{"NSObject", RecordLinkage::Exported
,
41 ObjCInterfaceRecord ClassEH
{"NSObject", RecordLinkage::Exported
,
42 CompleteInterface
| ObjCIFSymbolKind::EHType
};
44 EXPECT_TRUE(Class
.isExported());
45 EXPECT_EQ(Class
.isExported(), ClassEH
.isExported());
46 EXPECT_FALSE(Class
.hasExceptionAttribute());
47 EXPECT_TRUE(ClassEH
.hasExceptionAttribute());
48 EXPECT_EQ(ObjCIVarRecord::createScopedName("NSObject", "var"),
50 EXPECT_TRUE(Class
.isCompleteInterface());
51 EXPECT_TRUE(ClassEH
.isCompleteInterface());
52 EXPECT_TRUE(Class
.isExportedSymbol(ObjCIFSymbolKind::MetaClass
));
53 EXPECT_EQ(ClassEH
.getLinkageForSymbol(ObjCIFSymbolKind::EHType
),
54 RecordLinkage::Exported
);
57 TEST(TAPIRecord
, IncompleteObjC
) {
58 ObjCInterfaceRecord Class
{"NSObject", RecordLinkage::Rexported
,
59 ObjCIFSymbolKind::MetaClass
};
60 EXPECT_EQ(Class
.getLinkageForSymbol(ObjCIFSymbolKind::EHType
),
61 RecordLinkage::Unknown
);
62 EXPECT_EQ(Class
.getLinkageForSymbol(ObjCIFSymbolKind::MetaClass
),
63 RecordLinkage::Rexported
);
64 EXPECT_TRUE(Class
.isExportedSymbol(ObjCIFSymbolKind::MetaClass
));
65 EXPECT_FALSE(Class
.isCompleteInterface());
66 EXPECT_TRUE(Class
.isExported());
68 Class
.updateLinkageForSymbols(ObjCIFSymbolKind::Class
,
69 RecordLinkage::Internal
);
70 EXPECT_TRUE(Class
.isExported());
71 EXPECT_FALSE(Class
.isCompleteInterface());
72 EXPECT_FALSE(Class
.isExportedSymbol(ObjCIFSymbolKind::Class
));
73 EXPECT_EQ(Class
.getLinkageForSymbol(ObjCIFSymbolKind::Class
),
74 RecordLinkage::Internal
);
77 TEST(TAPIRecord
, SimpleSlice
) {
78 Triple
T("arm64-apple-macosx13.3");
79 RecordsSlice
Slice(T
);
80 EXPECT_TRUE(Slice
.empty());
81 Slice
.addRecord("_OBJC_CLASS_$_NSObject", SymbolFlags::None
,
82 GlobalRecord::Kind::Unknown
, RecordLinkage::Rexported
);
83 Slice
.addRecord("_OBJC_METACLASS_$_NSObject", SymbolFlags::None
,
84 GlobalRecord::Kind::Unknown
, RecordLinkage::Rexported
);
85 Slice
.addRecord("_OBJC_IVAR_$_NSConcreteValue.typeInfo", SymbolFlags::None
,
86 GlobalRecord::Kind::Unknown
, RecordLinkage::Exported
);
87 Slice
.addRecord("_OBJC_IVAR_$_NSObject.objInfo", SymbolFlags::None
,
88 GlobalRecord::Kind::Unknown
, RecordLinkage::Exported
);
89 Slice
.addRecord("_foo", SymbolFlags::WeakDefined
| SymbolFlags::Rexported
,
90 GlobalRecord::Kind::Variable
, RecordLinkage::Rexported
);
91 EXPECT_FALSE(Slice
.empty());
94 EXPECT_FALSE(Slice
.findGlobal("_foo", GlobalRecord::Kind::Function
));
95 auto *Global
= Slice
.findGlobal("_foo");
97 EXPECT_TRUE(Global
->isVariable());
98 EXPECT_TRUE(Global
->isWeakDefined());
99 EXPECT_TRUE(Global
->isRexported());
100 EXPECT_TRUE(Global
->isData());
103 auto *Class
= Slice
.findObjCInterface("NSObject");
105 EXPECT_TRUE(Class
->isRexported());
106 EXPECT_TRUE(Class
->isData());
107 EXPECT_FALSE(Class
->hasExceptionAttribute());
108 auto ClassIVar
= Class
->findObjCIVar("objInfo");
109 ASSERT_TRUE(ClassIVar
);
110 EXPECT_TRUE(ClassIVar
->isExported());
111 EXPECT_FALSE(ClassIVar
->isRexported());
113 // Check fall-back extension.
114 auto *Cat
= Slice
.findObjCCategory("NSConcreteValue", "");
116 // There is not linkage information for categories.
117 EXPECT_FALSE(Cat
->isExported());
118 EXPECT_FALSE(Cat
->isInternal());
119 auto CatIVar
= Cat
->findObjCIVar("typeInfo");
120 EXPECT_TRUE(CatIVar
);
121 EXPECT_TRUE(CatIVar
->isExported());
122 EXPECT_FALSE(CatIVar
->isRexported());
124 // Find IVars directly.
126 Slice
.findObjCIVar(/*IsScopedName=*/true, "NSConcreteValue.typeInfo");
128 EXPECT_EQ(CatIVar
->getName(), TIIVar
->getName());
130 auto OIIVar
= Slice
.findObjCIVar(/*IsScopedName=*/false, "objInfo");
132 EXPECT_EQ(ClassIVar
->getName(), OIIVar
->getName());
134 EXPECT_FALSE(Slice
.findObjCIVar(/*IsScopedName=*/true, "typeInfo"));
137 TEST(TAPIRecord
, LibraryAttrs
) {
138 Triple
T("arm64-apple-ios15.1");
139 RecordsSlice
Slice(T
);
140 EXPECT_TRUE(Slice
.empty());
142 auto BA
= Slice
.getBinaryAttrs();
143 EXPECT_TRUE(Slice
.hasBinaryAttrs());
146 } // namespace TAPIRecord