For the purposes of building LLVM types, a forward-declared
enumeration type with a fixed underlying type is complete. Fixes
<rdar://problem/10916155>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151403 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 0346519..2da6cf0 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -199,8 +199,13 @@
// If it's a tagged type used by-value, but is just a forward decl, we can't
// convert it. Note that getDefinition()==0 is not the same as !isDefinition.
- if (TT->getDecl()->getDefinition() == 0)
+ // The exception is an enumeration type with a fixed underlying type; these
+ // can be converted even if they are forward declarations.
+ if (TT->getDecl()->getDefinition() == 0 &&
+ !(isa<EnumDecl>(TT->getDecl()) &&
+ cast<EnumDecl>(TT->getDecl())->isFixed())) {
return false;
+ }
// If this is an enum, then it is always safe to convert.
const RecordType *RT = dyn_cast<RecordType>(TT);
diff --git a/test/CodeGenCXX/forward-enum.cpp b/test/CodeGenCXX/forward-enum.cpp
new file mode 100644
index 0000000..c1169e0
--- /dev/null
+++ b/test/CodeGenCXX/forward-enum.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin11.0.0 -emit-llvm -o - %s | FileCheck %s
+
+enum MyEnum : char;
+void bar(MyEnum value) { }
+
+// CHECK: define void @_Z3foo6MyEnum
+void foo(MyEnum value)
+{
+ // CHECK: call void @_Z3bar6MyEnum(i8 signext
+ bar(value);
+}