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
13using namespace llvm;
14using namespace llvm::MachO;
15
16namespace TAPIRecord {
17
18TEST(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
36TEST(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
57TEST(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
77TEST(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
137TEST(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

source code of llvm/unittests/TextAPI/RecordTests.cpp