xref: /llvm-project/llvm/unittests/TextAPI/RecordTests.cpp (revision 50ae8a2a38b618d76193bed04b1d7df6890d5c8a)
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 
TEST(TAPIRecord,Simple)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 
TEST(TAPIRecord,SimpleObjC)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 
TEST(TAPIRecord,IncompleteObjC)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(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);
75 }
76 
TEST(TAPIRecord,SimpleSlice)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());
92 
93   // Check global.
94   EXPECT_FALSE(Slice.findGlobal("_foo", GlobalRecord::Kind::Function));
95   auto *Global = Slice.findGlobal("_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("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("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("NSConcreteValue", "");
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("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, "NSConcreteValue.typeInfo");
127   ASSERT_TRUE(TIIVar);
128   EXPECT_EQ(CatIVar->getName(), TIIVar->getName());
129 
130   auto OIIVar = Slice.findObjCIVar(/*IsScopedName=*/false, "objInfo");
131   ASSERT_TRUE(OIIVar);
132   EXPECT_EQ(ClassIVar->getName(), OIIVar->getName());
133 
134   EXPECT_FALSE(Slice.findObjCIVar(/*IsScopedName=*/true, "typeInfo"));
135 }
136 
TEST(TAPIRecord,LibraryAttrs)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