Skip to content

Commit 8cf3a82

Browse files
committed
AST: Fix crash on references to @cdecl enums at code generation
Add related end-to-end test.
1 parent beb980b commit 8cf3a82

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

lib/AST/ClangTypeConverter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,13 @@ clang::QualType ClangTypeConverter::visitEnumType(EnumType *type) {
653653
if (type->isUninhabited())
654654
return convert(Context.TheEmptyTupleType);
655655

656-
if (!type->getDecl()->isObjC())
657-
// Can't translate something not marked with @objc
656+
auto ED = type->getDecl();
657+
if (!ED->isObjC() && !ED->getAttrs().hasAttribute<CDeclAttr>())
658+
// Can't translate something not marked with @objc or @cdecl.
658659
return clang::QualType();
659660

660661
// @objc enums lower to their raw types.
661-
return convert(type->getDecl()->getRawType());
662+
return convert(ED->getRawType());
662663
}
663664

664665
template <bool templateArgument>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t --leading-lines
3+
4+
/// Generate an internal cdecl.h
5+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) \
6+
// RUN: %t/Lib.swift -emit-module -verify -o %t -emit-module-doc \
7+
// RUN: -emit-clang-header-path %t/cdecl.h \
8+
// RUN: -enable-experimental-feature CDecl
9+
10+
/// Build and run a binary from Swift and C code.
11+
// RUN: %clang-no-modules -c %t/Client.c -o %t/Client.o \
12+
// RUN: -I %t -I %clang-include-dir -Werror -isysroot %sdk
13+
// RUN: %target-build-swift %t/Lib.swift %t/Client.o -O -o %t/a.out \
14+
// RUN: -enable-experimental-feature CDecl -parse-as-library
15+
// RUN: %target-codesign %t/a.out
16+
// RUN: %target-run %t/a.out > %t/run.log
17+
// RUN: %FileCheck %s --input-file %t/run.log
18+
19+
// REQUIRES: swift_feature_CDecl
20+
// REQUIRES: executable_test
21+
22+
//--- Lib.swift
23+
24+
/// My documentation
25+
@cdecl(simple) public func simpleNameSwiftSide(x: CInt, bar y: CInt) -> CInt {
26+
print(x, y)
27+
return x
28+
}
29+
30+
@cdecl func defaultName(x: Int) {
31+
print(x)
32+
}
33+
34+
@cdecl public func primitiveTypes(i: Int, ci: CInt, l: CLong, c: CChar, f: Float, d: Double, b: Bool) {
35+
print(i, ci, l, c, f, d, b)
36+
}
37+
38+
@cdecl enum CEnum: CInt { case A, B }
39+
40+
@cdecl func useEnum(e: CEnum) -> CEnum {
41+
print(e)
42+
return e
43+
}
44+
45+
//--- Client.c
46+
47+
#include <stdio.h>
48+
#include "cdecl.h"
49+
50+
int main() {
51+
int x = simple(42, 43);
52+
// CHECK: 42 43
53+
printf("%d\n", x);
54+
// CHECK-NEXT: 42
55+
56+
defaultName(121);
57+
// CHECK-NEXT: 121
58+
59+
primitiveTypes(1, 2, 3, 'a', 1.0f, 2.0, true);
60+
// CHECK-NEXT: 1 2 3 97 1.0 2.0 true
61+
62+
CEnum e = useEnum(CEnumB);
63+
// CHECK-NEXT: B
64+
printf("%d\n", e);
65+
// CHECK-NEXT: 1
66+
}

0 commit comments

Comments
 (0)