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
TEST_P(ImportObjCDecl,ImplicitlyDeclareSelf)27 TEST_P(ImportObjCDecl, ImplicitlyDeclareSelf) {
28 Decl *FromTU = getTuDecl(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_OBJCXX, "input.mm");
40 auto *FromMethod = LastDeclMatcher<ObjCMethodDecl>().match(
41 FromTU, namedDecl(hasName("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
TEST_P(ImportObjCDecl,ObjPropertyNameConflict)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(R"(
55 @interface DupProp{}
56 @property (class) int prop;
57 @property int prop;
58 @end
59 )",
60 Lang_OBJCXX, "input.mm");
61 auto *FromClass = FirstDeclMatcher<ObjCInterfaceDecl>().match(
62 FromTU, namedDecl(hasName("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 static const auto ObjCTestArrayForRunOptions =
81 std::array<std::vector<std::string>, 2>{
82 {std::vector<std::string>{"-fno-objc-arc"},
83 std::vector<std::string>{"-fobjc-arc"}}};
84
85 const auto ObjCTestValuesForRunOptions =
86 ::testing::ValuesIn(ObjCTestArrayForRunOptions);
87
88 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportObjCDecl,
89 ObjCTestValuesForRunOptions);
90