1 | //===-- RecordTests.cpp - TextAPI Record Type Test-------------------------===// |
2 | // |
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 |
6 | // |
7 | //===-----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/TargetParser/Triple.h" |
10 | #include "llvm/TextAPI/RecordsSlice.h" |
11 | #include "gtest/gtest.h" |
12 | |
13 | using namespace llvm; |
14 | using namespace llvm::MachO; |
15 | |
16 | namespace TAPIRecord { |
17 | |
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()); |
34 | } |
35 | |
36 | TEST(TAPIRecord, SimpleObjC) { |
37 | const ObjCIFSymbolKind CompleteInterface = |
38 | ObjCIFSymbolKind::Class | ObjCIFSymbolKind::MetaClass; |
39 | ObjCInterfaceRecord Class{"NSObject" , RecordLinkage::Exported, |
40 | CompleteInterface}; |
41 | ObjCInterfaceRecord ClassEH{"NSObject" , RecordLinkage::Exported, |
42 | CompleteInterface | ObjCIFSymbolKind::EHType}; |
43 | |
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" ), |
49 | "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); |
55 | } |
56 | |
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()); |
67 | |
68 | Class.updateLinkageForSymbols(SymType: ObjCIFSymbolKind::Class, |
69 | Link: 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); |
75 | } |
76 | |
77 | TEST(TAPIRecord, SimpleSlice) { |
78 | Triple T("arm64-apple-macosx13.3" ); |
79 | RecordsSlice Slice(T); |
80 | EXPECT_TRUE(Slice.empty()); |
81 | Slice.addRecord(Name: "_OBJC_CLASS_$_NSObject" , Flags: SymbolFlags::None, |
82 | GV: GlobalRecord::Kind::Unknown, Linkage: RecordLinkage::Rexported); |
83 | Slice.addRecord(Name: "_OBJC_METACLASS_$_NSObject" , Flags: SymbolFlags::None, |
84 | GV: GlobalRecord::Kind::Unknown, Linkage: RecordLinkage::Rexported); |
85 | Slice.addRecord(Name: "_OBJC_IVAR_$_NSConcreteValue.typeInfo" , Flags: SymbolFlags::None, |
86 | GV: GlobalRecord::Kind::Unknown, Linkage: RecordLinkage::Exported); |
87 | Slice.addRecord(Name: "_OBJC_IVAR_$_NSObject.objInfo" , Flags: SymbolFlags::None, |
88 | GV: GlobalRecord::Kind::Unknown, Linkage: RecordLinkage::Exported); |
89 | Slice.addRecord(Name: "_foo" , Flags: SymbolFlags::WeakDefined | SymbolFlags::Rexported, |
90 | GV: GlobalRecord::Kind::Variable, Linkage: RecordLinkage::Rexported); |
91 | EXPECT_FALSE(Slice.empty()); |
92 | |
93 | // Check global. |
94 | EXPECT_FALSE(Slice.findGlobal("_foo" , GlobalRecord::Kind::Function)); |
95 | auto *Global = Slice.findGlobal(Name: "_foo" ); |
96 | ASSERT_TRUE(Global); |
97 | EXPECT_TRUE(Global->isVariable()); |
98 | EXPECT_TRUE(Global->isWeakDefined()); |
99 | EXPECT_TRUE(Global->isRexported()); |
100 | EXPECT_TRUE(Global->isData()); |
101 | |
102 | // Check class. |
103 | auto *Class = Slice.findObjCInterface(Name: "NSObject" ); |
104 | ASSERT_TRUE(Class); |
105 | EXPECT_TRUE(Class->isRexported()); |
106 | EXPECT_TRUE(Class->isData()); |
107 | EXPECT_FALSE(Class->hasExceptionAttribute()); |
108 | auto ClassIVar = Class->findObjCIVar(IVar: "objInfo" ); |
109 | ASSERT_TRUE(ClassIVar); |
110 | EXPECT_TRUE(ClassIVar->isExported()); |
111 | EXPECT_FALSE(ClassIVar->isRexported()); |
112 | |
113 | // Check fall-back extension. |
114 | auto *Cat = Slice.findObjCCategory(ClassToExtend: "NSConcreteValue" , Category: "" ); |
115 | ASSERT_TRUE(Cat); |
116 | // There is not linkage information for categories. |
117 | EXPECT_FALSE(Cat->isExported()); |
118 | EXPECT_FALSE(Cat->isInternal()); |
119 | auto CatIVar = Cat->findObjCIVar(IVar: "typeInfo" ); |
120 | EXPECT_TRUE(CatIVar); |
121 | EXPECT_TRUE(CatIVar->isExported()); |
122 | EXPECT_FALSE(CatIVar->isRexported()); |
123 | |
124 | // Find IVars directly. |
125 | auto TIIVar = |
126 | Slice.findObjCIVar(/*IsScopedName=*/true, Name: "NSConcreteValue.typeInfo" ); |
127 | ASSERT_TRUE(TIIVar); |
128 | EXPECT_EQ(CatIVar->getName(), TIIVar->getName()); |
129 | |
130 | auto OIIVar = Slice.findObjCIVar(/*IsScopedName=*/false, Name: "objInfo" ); |
131 | ASSERT_TRUE(OIIVar); |
132 | EXPECT_EQ(ClassIVar->getName(), OIIVar->getName()); |
133 | |
134 | EXPECT_FALSE(Slice.findObjCIVar(/*IsScopedName=*/true, "typeInfo" )); |
135 | } |
136 | |
137 | TEST(TAPIRecord, LibraryAttrs) { |
138 | Triple T("arm64-apple-ios15.1" ); |
139 | RecordsSlice Slice(T); |
140 | EXPECT_TRUE(Slice.empty()); |
141 | |
142 | auto BA = Slice.getBinaryAttrs(); |
143 | EXPECT_TRUE(Slice.hasBinaryAttrs()); |
144 | } |
145 | |
146 | } // namespace TAPIRecord |
147 | |