1 | //===- unittest/AST/ASTImporterObjCTest.cpp -============================--===// |
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 | // Tests for the correct import of AST nodes related to Objective-C and |
10 | // Objective-C++. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "clang/AST/DeclContextInternals.h" |
15 | #include "clang/ASTMatchers/ASTMatchers.h" |
16 | #include "gtest/gtest.h" |
17 | |
18 | #include "ASTImporterFixtures.h" |
19 | |
20 | using namespace clang::ast_matchers; |
21 | using namespace clang; |
22 | |
23 | namespace { |
24 | struct ImportObjCDecl : ASTImporterOptionSpecificTestBase {}; |
25 | } // namespace |
26 | |
27 | TEST_P(ImportObjCDecl, ImplicitlyDeclareSelf) { |
28 | Decl *FromTU = getTuDecl(SrcCode: R"( |
29 | __attribute__((objc_root_class)) |
30 | @interface Root |
31 | @end |
32 | @interface C : Root |
33 | -(void)method; |
34 | @end |
35 | @implementation C |
36 | -(void)method {} |
37 | @end |
38 | )" , |
39 | Lang: Lang_OBJCXX, FileName: "input.mm" ); |
40 | auto *FromMethod = LastDeclMatcher<ObjCMethodDecl>().match( |
41 | D: FromTU, AMatcher: namedDecl(hasName(Name: "method" ))); |
42 | ASSERT_TRUE(FromMethod); |
43 | auto ToMethod = Import(FromMethod, Lang_OBJCXX); |
44 | ASSERT_TRUE(ToMethod); |
45 | |
46 | // Both methods should have their implicit parameters. |
47 | EXPECT_TRUE(FromMethod->getSelfDecl() != nullptr); |
48 | EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr); |
49 | } |
50 | |
51 | TEST_P(ImportObjCDecl, ObjPropertyNameConflict) { |
52 | // Tests that properties that share the same name are correctly imported. |
53 | // This is only possible with one instance and one class property. |
54 | Decl *FromTU = getTuDecl(SrcCode: R"( |
55 | @interface DupProp{} |
56 | @property (class) int prop; |
57 | @property int prop; |
58 | @end |
59 | )" , |
60 | Lang: Lang_OBJCXX, FileName: "input.mm" ); |
61 | auto *FromClass = FirstDeclMatcher<ObjCInterfaceDecl>().match( |
62 | D: FromTU, AMatcher: namedDecl(hasName(Name: "DupProp" ))); |
63 | auto ToClass = Import(FromClass, Lang_OBJCXX); |
64 | ASSERT_TRUE(ToClass); |
65 | // We should have one class and one instance property. |
66 | ASSERT_EQ( |
67 | 1, std::distance(ToClass->classprop_begin(), ToClass->classprop_end())); |
68 | ASSERT_EQ(1, |
69 | std::distance(ToClass->instprop_begin(), ToClass->instprop_end())); |
70 | for (clang::ObjCPropertyDecl *prop : ToClass->properties()) { |
71 | // All properties should have a getter and a setter. |
72 | ASSERT_TRUE(prop->getGetterMethodDecl()); |
73 | ASSERT_TRUE(prop->getSetterMethodDecl()); |
74 | // The getters/setters should be able to find the right associated property. |
75 | ASSERT_EQ(prop->getGetterMethodDecl()->findPropertyDecl(), prop); |
76 | ASSERT_EQ(prop->getSetterMethodDecl()->findPropertyDecl(), prop); |
77 | } |
78 | } |
79 | |
80 | TEST_P(ImportObjCDecl, ImportObjCTypeParamDecl) { |
81 | Decl *FromTU = getTuDecl( |
82 | SrcCode: R"( |
83 | @interface X <FirstParam: id> |
84 | @end |
85 | )" , |
86 | Lang: Lang_OBJCXX, FileName: "input.mm" ); |
87 | auto *FromInterfaceDecl = FirstDeclMatcher<ObjCInterfaceDecl>().match( |
88 | D: FromTU, AMatcher: namedDecl(hasName(Name: "X" ))); |
89 | auto *FromTypeParamDecl = |
90 | FromInterfaceDecl->getTypeParamListAsWritten()->front(); |
91 | |
92 | auto *ToTypeParamDeclImported = Import(FromTypeParamDecl, Lang_OBJCXX); |
93 | ASSERT_TRUE(ToTypeParamDeclImported); |
94 | } |
95 | |
96 | static const auto ObjCTestArrayForRunOptions = |
97 | std::array<std::vector<std::string>, 2>{ |
98 | ._M_elems: {std::vector<std::string>{"-fno-objc-arc" }, |
99 | std::vector<std::string>{"-fobjc-arc" }}}; |
100 | |
101 | const auto ObjCTestValuesForRunOptions = |
102 | ::testing::ValuesIn(container: ObjCTestArrayForRunOptions); |
103 | |
104 | INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportObjCDecl, |
105 | ObjCTestValuesForRunOptions); |
106 | |