Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion lib/ClangImporter/ImportName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
#include "clang/Sema/Lookup.h"
Expand Down Expand Up @@ -1410,12 +1411,35 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
case clang::DeclarationName::CXXConversionFunctionName:
case clang::DeclarationName::CXXDestructorName:
case clang::DeclarationName::CXXLiteralOperatorName:
case clang::DeclarationName::CXXOperatorName:
case clang::DeclarationName::CXXUsingDirective:
case clang::DeclarationName::CXXDeductionGuideName:
// TODO: Handling these is part of C++ interoperability.
return ImportedName();

case clang::DeclarationName::CXXOperatorName: {
auto op = D->getDeclName().getCXXOverloadedOperator();
switch (op) {
case clang::OverloadedOperatorKind::OO_Plus:
case clang::OverloadedOperatorKind::OO_Minus:
case clang::OverloadedOperatorKind::OO_Star:
case clang::OverloadedOperatorKind::OO_Slash:
if (auto FD = dyn_cast<clang::FunctionDecl>(D)) {
baseName = clang::getOperatorSpelling(op);
isFunction = true;
argumentNames.resize(FD->param_size());
} else {
// This can happen for example for templated operators functions.
// We don't support those, yet.
return ImportedName();
}
break;
default:
// We don't import these yet.
return ImportedName();
}
break;
}

case clang::DeclarationName::Identifier:
// Map the identifier.
baseName = D->getDeclName().getAsIdentifierInfo()->getName();
Expand Down
3 changes: 3 additions & 0 deletions test/Interop/Cxx/operators/Inputs/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module NonMemberInline {
header "non-member-inline.h"
}
28 changes: 28 additions & 0 deletions test/Interop/Cxx/operators/Inputs/non-member-inline.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef TEST_INTEROP_CXX_OPERATORS_INPUTS_NON_MEMBER_INLINE_H
#define TEST_INTEROP_CXX_OPERATORS_INPUTS_NON_MEMBER_INLINE_H

struct IntBox {
int value;
};

inline IntBox operator+(IntBox lhs, IntBox rhs) {
return IntBox{.value = lhs.value + rhs.value};
}

inline IntBox operator-(IntBox lhs, IntBox rhs) {
return IntBox{.value = lhs.value - rhs.value};
}

inline IntBox operator*(IntBox lhs, IntBox rhs) {
return IntBox{.value = lhs.value * rhs.value};
}

inline IntBox operator/(IntBox lhs, IntBox rhs) {
return IntBox{.value = lhs.value / rhs.value};
}

// Make sure that we don't crash on templated operators
template<typename T> struct S {};
template<typename T> S<T> operator+(S<T> lhs, S<T> rhs);

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: %target-swift-ide-test -print-module -module-to-print=NonMemberInline -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s

// CHECK: func + (lhs: IntBox, rhs: IntBox) -> IntBox
// CHECK-NEXT: func - (lhs: IntBox, rhs: IntBox) -> IntBox
// CHECK-NEXT: func * (lhs: IntBox, rhs: IntBox) -> IntBox
// CHECK-NEXT: func / (lhs: IntBox, rhs: IntBox) -> IntBox
11 changes: 11 additions & 0 deletions test/Interop/Cxx/operators/non-member-inline-typechecker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %target-typecheck-verify-swift -I %S/Inputs -enable-cxx-interop

import NonMemberInline

var lhs = IntBox(value: 42)
var rhs = IntBox(value: 23)

let resultPlus = lhs + rhs
let resultMinus = lhs - rhs
let resultStar = lhs * rhs
let resultSlash = lhs / rhs
46 changes: 46 additions & 0 deletions test/Interop/Cxx/operators/non-member-inline.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-cxx-interop)
//
// REQUIRES: executable_test

import NonMemberInline
import StdlibUnittest

var OperatorsTestSuite = TestSuite("Operators")

OperatorsTestSuite.test("plus") {
let lhs = IntBox(value: 42)
let rhs = IntBox(value: 23)

let result = lhs + rhs

expectEqual(65, result.value)
}

OperatorsTestSuite.test("minus") {
let lhs = IntBox(value: 42)
let rhs = IntBox(value: 23)

let result = lhs - rhs

expectEqual(19, result.value)
}

OperatorsTestSuite.test("star") {
let lhs = IntBox(value: 42)
let rhs = IntBox(value: 23)

let result = lhs * rhs

expectEqual(966, result.value)
}

OperatorsTestSuite.test("slash") {
let lhs = IntBox(value: 42)
let rhs = IntBox(value: 23)

let result = lhs / rhs

expectEqual(1, result.value)
}

runAllTests()