Pull CodeGenFunction::EmitVAArg into target specific ABIInfo classes.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64235 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index fbaffad..22afb5d 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -244,6 +244,9 @@
          it != ie; ++it)
       it->info = classifyArgumentType(it->type, Context);
   }
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
 };
 
 /// X86_32ABIInfo - The X86-32 ABI information.
@@ -261,6 +264,9 @@
          it != ie; ++it)
       it->info = classifyArgumentType(it->type, Context);
   }
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
 };
 }
 
@@ -312,7 +318,7 @@
 }
 
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
-                                              ASTContext &Context) const {
+                                               ASTContext &Context) const {
   // FIXME: Set alignment on indirect arguments.
   if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
     // Structures with flexible arrays are always indirect.
@@ -340,6 +346,33 @@
   }
 }
 
+llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                      CodeGenFunction &CGF) const {
+  const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
+
+  CGBuilderTy &Builder = CGF.Builder;
+  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, 
+                                                       "ap");
+  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+  llvm::Type *PTy = 
+    llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+  llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
+  
+  uint64_t SizeInBytes = CGF.getContext().getTypeSize(Ty) / 8;
+  const unsigned ArgumentSizeInBytes = 4;
+  if (SizeInBytes < ArgumentSizeInBytes)
+    SizeInBytes = ArgumentSizeInBytes;
+
+  llvm::Value *NextAddr = 
+    Builder.CreateGEP(Addr, 
+                      llvm::ConstantInt::get(llvm::Type::Int32Ty, SizeInBytes),
+                      "ap.next");
+  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+
+  return AddrTyped;
+}
+
 namespace {
 /// X86_64ABIInfo - The X86_64 ABI information.
 class X86_64ABIInfo : public ABIInfo {
@@ -399,6 +432,9 @@
 
 public:
   virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context) const;
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const;
 };
 }
 
@@ -815,8 +851,13 @@
   }
 }
 
+llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                      CodeGenFunction &CGF) const {
+  return 0;
+}
+
 ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy,
-                                            ASTContext &Context) const {
+                                              ASTContext &Context) const {
   if (RetTy->isVoidType()) {
     return ABIArgInfo::getIgnore();
   } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
@@ -827,7 +868,7 @@
 }
 
 ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
-                                              ASTContext &Context) const {
+                                                ASTContext &Context) const {
   if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
     return ABIArgInfo::getIndirect(0);
   } else {
@@ -835,6 +876,11 @@
   }
 }
 
+llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                       CodeGenFunction &CGF) const {
+  return 0;
+}
+
 const ABIInfo &CodeGenTypes::getABIInfo() const {
   if (TheABIInfo)
     return *TheABIInfo;
@@ -1490,3 +1536,9 @@
   assert(0 && "Unhandled ABIArgInfo::Kind");
   return RValue::get(0);
 }
+
+/* VarArg handling */
+
+llvm::Value *CodeGenFunction::EmitVAArg(llvm::Value *VAListAddr, QualType Ty) {
+  return CGM.getTypes().getABIInfo().EmitVAArg(VAListAddr, Ty, *this);
+}