implement proper support for _Bool in memory, which is usually i8, not i1.
This fixes a crash reported by Seo Sanghyeon


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45778 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGDecl.cpp b/CodeGen/CGDecl.cpp
index 69ffbbb..23c707d 100644
--- a/CodeGen/CGDecl.cpp
+++ b/CodeGen/CGDecl.cpp
@@ -71,7 +71,7 @@
   llvm::Value *&DMEntry = LocalDeclMap[&D];
   assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
   
-  const llvm::Type *LTy = ConvertType(Ty);
+  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
   llvm::Constant *Init = 0;
   if (D.getInit() == 0) {
     Init = llvm::Constant::getNullValue(LTy);
diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp
index 866ba47..9a65d2e 100644
--- a/CodeGen/CodeGenModule.cpp
+++ b/CodeGen/CodeGenModule.cpp
@@ -121,7 +121,7 @@
   llvm::Constant *&Entry = GlobalDeclMap[D];
   if (Entry) return Entry;
   
-  const llvm::Type *Ty = getTypes().ConvertType(D->getType());
+  const llvm::Type *Ty = getTypes().ConvertTypeForMem(D->getType());
 
   // Check to see if the global already exists.
   llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName());
diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp
index 0de6dc8..e2a5798 100644
--- a/CodeGen/CodeGenTypes.cpp
+++ b/CodeGen/CodeGenTypes.cpp
@@ -149,6 +149,25 @@
   return ResultType;
 }
 
+/// ConvertTypeForMem - Convert type T into a llvm::Type. Maintain and use
+/// type cache through TypeHolderMap.  This differs from ConvertType in that
+/// it is used to convert to the memory representation for a type.  For
+/// example, the scalar representation for _Bool is i1, but the memory
+/// representation is usually i8 or i32, depending on the target.
+const llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
+  const llvm::Type *R = ConvertType(T);
+  
+  // If this is a non-bool type, don't map it.
+  if (R != llvm::Type::Int1Ty)
+    return R;
+    
+  // Otherwise, return an integer of the target-specified size.
+  unsigned BoolWidth = (unsigned)Context.getTypeSize(T, SourceLocation());
+  return llvm::IntegerType::get(BoolWidth);
+  
+}
+
+
 const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
   const clang::Type &Ty = *T.getCanonicalType();
   
@@ -165,8 +184,7 @@
       return llvm::IntegerType::get(8);
 
     case BuiltinType::Bool:
-      // FIXME: This is very strange.  We want scalars to be i1, but in memory
-      // they can be i1 or i32.  Should the codegen handle this issue?
+      // Note that we always return bool as i1 for use as a scalar type.
       return llvm::Type::Int1Ty;
       
     case BuiltinType::Char_S:
diff --git a/CodeGen/CodeGenTypes.h b/CodeGen/CodeGenTypes.h
index 14f8961..f10dc53 100644
--- a/CodeGen/CodeGenTypes.h
+++ b/CodeGen/CodeGenTypes.h
@@ -118,16 +118,26 @@
   ASTContext &getContext() const { return Context; }
 
   /// ConvertType - Convert type T into a llvm::Type. Maintain and use
-  /// type cache through TypeHOlderMap.
+  /// type cache through TypeHolderMap.
   const llvm::Type *ConvertType(QualType T);
-  void DecodeArgumentTypes(const FunctionTypeProto &FTP, 
-                           std::vector<const llvm::Type*> &ArgTys);
-
+  
+  /// ConvertTypeForMem - Convert type T into a llvm::Type. Maintain and use
+  /// type cache through TypeHolderMap.  This differs from ConvertType in that
+  /// it is used to convert to the memory representation for a type.  For
+  /// example, the scalar representation for _Bool is i1, but the memory
+  /// representation is usually i8 or i32, depending on the target.
+  const llvm::Type *ConvertTypeForMem(QualType T);
+  
+  
   const CGRecordLayout *getCGRecordLayout(const llvm::Type*) const;
   
   /// getLLVMFieldNo - Return llvm::StructType element number
   /// that corresponds to the field FD.
   unsigned getLLVMFieldNo(const FieldDecl *FD);
+    
+public:  // These are internal details of CGT that shouldn't be used externally.
+  void DecodeArgumentTypes(const FunctionTypeProto &FTP, 
+                           std::vector<const llvm::Type*> &ArgTys);
 
   /// addFieldInfo - Assign field number to field FD.
   void addFieldInfo(const FieldDecl *FD, unsigned No, unsigned Begin,