Add Ignore ABIArgInfo kind, for handling void & empty structures.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63039 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index cf0d4cc..cd78178 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -113,6 +113,9 @@
                /// allocated location passed as an implicit first
                /// argument to the function.
 
+    Ignore,    /// Ignore the argument (treat as void). Useful for
+               /// void and empty structs.
+
     Coerce,    /// Only valid for aggregate return types, the argument
                /// should be accessed by coercion to a provided type.
 
@@ -147,6 +150,9 @@
   static ABIArgInfo getStructRet() { 
     return ABIArgInfo(StructRet); 
   }
+  static ABIArgInfo getIgnore() {
+    return ABIArgInfo(Ignore);
+  }
   static ABIArgInfo getCoerce(const llvm::Type *T) { 
     assert(T->isSingleValueType() && "Can only coerce to simple types");
     return ABIArgInfo(Coerce, T);
@@ -161,6 +167,7 @@
   Kind getKind() const { return TheKind; }
   bool isDefault() const { return TheKind == Default; }
   bool isStructRet() const { return TheKind == StructRet; }
+  bool isIgnore() const { return TheKind == Ignore; }
   bool isCoerce() const { return TheKind == Coerce; }
   bool isByVal() const { return TheKind == ByVal; }
   bool isExpand() const { return TheKind == Expand; }
@@ -432,7 +439,9 @@
   if (const BuiltinType *BT = Ty->getAsBuiltinType()) {
     BuiltinType::Kind k = BT->getKind();
 
-    if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) {
+    if (k == BuiltinType::Void) {
+      Lo = NoClass; 
+    } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) {
       Lo = Integer;
     } else if (k == BuiltinType::Float || k == BuiltinType::Double) {
       Lo = SSE;
@@ -468,7 +477,7 @@
   const llvm::Type *ResType = 0;
   switch (Lo) {
   case NoClass:
-    assert(0 && "FIXME: Handle ignored return values.");
+    return ABIArgInfo::getIgnore();
 
   case SSEUp:
   case X87Up:
@@ -719,6 +728,10 @@
     break;
   }
 
+  case ABIArgInfo::Ignore:
+    ResultType = llvm::Type::VoidTy;
+    break;
+
   case ABIArgInfo::Coerce:
     ResultType = RetAI.getCoerceToType();
     break;
@@ -729,6 +742,9 @@
     const llvm::Type *Ty = ConvertType(*begin);
     
     switch (AI.getKind()) {
+    case ABIArgInfo::Ignore:
+      break;
+
     case ABIArgInfo::Coerce:
     case ABIArgInfo::StructRet:
       assert(0 && "Invalid ABI kind for non-return argument");
@@ -795,6 +811,7 @@
     ++Index;
     break;
 
+  case ABIArgInfo::Ignore:
   case ABIArgInfo::Coerce:
     break;
 
@@ -830,6 +847,10 @@
       }
       break;
      
+    case ABIArgInfo::Ignore:
+      // Skip increment, no matching LLVM parameter.
+      continue; 
+
     case ABIArgInfo::Expand: {
       std::vector<const llvm::Type*> Tys;  
       // FIXME: This is rather inefficient. Do we ever actually need
@@ -900,7 +921,10 @@
         AI->setName(Name + "." + llvm::utostr(Index));
       continue;
     }
-      
+
+    case ABIArgInfo::Ignore:
+      break;
+
     case ABIArgInfo::Coerce:
     case ABIArgInfo::StructRet:
       assert(0 && "Invalid ABI kind for non-return argument");        
@@ -937,6 +961,9 @@
       RV = Builder.CreateLoad(ReturnValue);
       break;
 
+    case ABIArgInfo::Ignore:
+      break;
+      
     case ABIArgInfo::Coerce: {
       const llvm::Type *CoerceToPTy = 
         llvm::PointerType::getUnqual(RetAI.getCoerceToType());
@@ -972,6 +999,7 @@
     break;
     
   case ABIArgInfo::Default:
+  case ABIArgInfo::Ignore:
   case ABIArgInfo::Coerce:
     break;
 
@@ -999,6 +1027,9 @@
       }
       break;
      
+    case ABIArgInfo::Ignore:
+      break;
+
     case ABIArgInfo::StructRet:
     case ABIArgInfo::Coerce:
       assert(0 && "Invalid ABI kind for non-return argument");
@@ -1038,6 +1069,9 @@
   case ABIArgInfo::Default:
     return RValue::get(RetTy->isVoidType() ? 0 : CI);
 
+  case ABIArgInfo::Ignore:
+    return RValue::get(0);
+
   case ABIArgInfo::Coerce: {
     const llvm::Type *CoerceToPTy = 
       llvm::PointerType::getUnqual(RetAI.getCoerceToType());
@@ -1045,8 +1079,10 @@
     Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy));
     if (RetTy->isAnyComplexType())
       return RValue::getComplex(LoadComplexFromAddr(V, false));
-    else
+    else if (CodeGenFunction::hasAggregateLLVMType(RetTy))
       return RValue::getAggregate(V);
+    else
+      return RValue::get(Builder.CreateLoad(V));
   }
 
   case ABIArgInfo::ByVal: