2021-03-23 20:55:44 +08:00
|
|
|
//===- unittest/AST/ASTImporterObjCTest.cpp -============================--===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Tests for the correct import of AST nodes related to Objective-C and
|
|
|
|
// Objective-C++.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/AST/DeclContextInternals.h"
|
|
|
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
#include "ASTImporterFixtures.h"
|
|
|
|
|
|
|
|
using namespace clang::ast_matchers;
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
struct ImportObjCDecl : ASTImporterOptionSpecificTestBase {};
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
TEST_P(ImportObjCDecl, ImplicitlyDeclareSelf) {
|
|
|
|
Decl *FromTU = getTuDecl(R"(
|
|
|
|
__attribute__((objc_root_class))
|
|
|
|
@interface Root
|
|
|
|
@end
|
|
|
|
@interface C : Root
|
|
|
|
-(void)method;
|
|
|
|
@end
|
|
|
|
@implementation C
|
|
|
|
-(void)method {}
|
|
|
|
@end
|
|
|
|
)",
|
|
|
|
Lang_OBJCXX, "input.mm");
|
|
|
|
auto *FromMethod = LastDeclMatcher<ObjCMethodDecl>().match(
|
|
|
|
FromTU, namedDecl(hasName("method")));
|
|
|
|
ASSERT_TRUE(FromMethod);
|
|
|
|
auto ToMethod = Import(FromMethod, Lang_OBJCXX);
|
|
|
|
ASSERT_TRUE(ToMethod);
|
|
|
|
|
|
|
|
// Both methods should have their implicit parameters.
|
|
|
|
EXPECT_TRUE(FromMethod->getSelfDecl() != nullptr);
|
|
|
|
EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(ImportObjCDecl, ObjPropertyNameConflict) {
|
|
|
|
// Tests that properties that share the same name are correctly imported.
|
|
|
|
// This is only possible with one instance and one class property.
|
|
|
|
Decl *FromTU = getTuDecl(R"(
|
|
|
|
@interface DupProp{}
|
|
|
|
@property (class) int prop;
|
|
|
|
@property int prop;
|
|
|
|
@end
|
|
|
|
)",
|
|
|
|
Lang_OBJCXX, "input.mm");
|
|
|
|
auto *FromClass = FirstDeclMatcher<ObjCInterfaceDecl>().match(
|
|
|
|
FromTU, namedDecl(hasName("DupProp")));
|
|
|
|
auto ToClass = Import(FromClass, Lang_OBJCXX);
|
|
|
|
ASSERT_TRUE(ToClass);
|
|
|
|
// We should have one class and one instance property.
|
|
|
|
ASSERT_EQ(
|
|
|
|
1, std::distance(ToClass->classprop_begin(), ToClass->classprop_end()));
|
|
|
|
ASSERT_EQ(1,
|
|
|
|
std::distance(ToClass->instprop_begin(), ToClass->instprop_end()));
|
|
|
|
for (clang::ObjCPropertyDecl *prop : ToClass->properties()) {
|
|
|
|
// All properties should have a getter and a setter.
|
|
|
|
ASSERT_TRUE(prop->getGetterMethodDecl());
|
|
|
|
ASSERT_TRUE(prop->getSetterMethodDecl());
|
|
|
|
// The getters/setters should be able to find the right associated property.
|
|
|
|
ASSERT_EQ(prop->getGetterMethodDecl()->findPropertyDecl(), prop);
|
|
|
|
ASSERT_EQ(prop->getSetterMethodDecl()->findPropertyDecl(), prop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const auto ObjCTestArrayForRunOptions =
|
|
|
|
std::array<std::vector<std::string>, 2>{
|
|
|
|
{std::vector<std::string>{"-fno-objc-arc"},
|
|
|
|
std::vector<std::string>{"-fobjc-arc"}}};
|
|
|
|
|
|
|
|
const auto ObjCTestValuesForRunOptions =
|
|
|
|
::testing::ValuesIn(ObjCTestArrayForRunOptions);
|
|
|
|
|
2021-05-15 01:15:20 +08:00
|
|
|
INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportObjCDecl,
|
|
|
|
ObjCTestValuesForRunOptions);
|