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);
+}