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
20using namespace clang::ast_matchers;
21using namespace clang;
22
23namespace {
24struct ImportObjCDecl : ASTImporterOptionSpecificTestBase {};
25} // namespace
26
27TEST_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
51TEST_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
80TEST_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
96static 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
101const auto ObjCTestValuesForRunOptions =
102 ::testing::ValuesIn(container: ObjCTestArrayForRunOptions);
103
104INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportObjCDecl,
105 ObjCTestValuesForRunOptions);
106

source code of clang/unittests/AST/ASTImporterObjCTest.cpp