106 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// Tests for the correct import of AST nodes related to Objective-C and10// 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} // namespace26 27TEST_P(ImportObjCDecl, ImplicitlyDeclareSelf) {28 Decl *FromTU = getTuDecl(R"(29 __attribute__((objc_root_class))30 @interface Root31 @end32 @interface C : Root33 -(void)method;34 @end35 @implementation C36 -(void)method {}37 @end38 )",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 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(R"(55 @interface DupProp{}56 @property (class) int prop;57 @property int prop;58 @end59 )",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 80TEST_P(ImportObjCDecl, ImportObjCTypeParamDecl) {81 Decl *FromTU = getTuDecl(82 R"(83 @interface X <FirstParam: id>84 @end85 )",86 Lang_OBJCXX, "input.mm");87 auto *FromInterfaceDecl = FirstDeclMatcher<ObjCInterfaceDecl>().match(88 FromTU, namedDecl(hasName("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 {std::vector<std::string>{"-fno-objc-arc"},99 std::vector<std::string>{"-fobjc-arc"}}};100 101const auto ObjCTestValuesForRunOptions =102 ::testing::ValuesIn(ObjCTestArrayForRunOptions);103 104INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportObjCDecl,105 ObjCTestValuesForRunOptions);106