]> granicus.if.org Git - clang/commitdiff
Implement __builtin_va_copy
authorAnders Carlsson <andersca@mac.com>
Sat, 9 Feb 2008 20:26:43 +0000 (20:26 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 9 Feb 2008 20:26:43 +0000 (20:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46911 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGBuiltin.cpp

index 661c09d7cd71d6c935fa3b06d0314968f2a1ab1a..83c5e60475cc47b31eeff518b5caf5389934b41e 100644 (file)
@@ -125,6 +125,25 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
       Intrinsic::vastart : Intrinsic::vaend;
     return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
   }
+  case Builtin::BI__builtin_va_copy: {
+    // FIXME: This does not yet handle architectures where va_list is a struct.
+    Value *DstPtr = EmitScalarExpr(E->getArg(0));
+    Value *SrcValue = EmitScalarExpr(E->getArg(1));
+    
+    Value *SrcPtr = CreateTempAlloca(SrcValue->getType(), "dst_ptr");
+    
+    // FIXME: Volatile
+    Builder.CreateStore(SrcValue, SrcPtr, false);
+
+    const llvm::Type *Type = 
+      llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+
+    DstPtr = Builder.CreateBitCast(DstPtr, Type);
+    SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
+    Value *Args[] = { DstPtr, SrcPtr };
+    return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), 
+                                          &Args[0], &Args[2]));
+  }
   case Builtin::BI__builtin_classify_type: {
     APSInt Result(32);
     if (!E->isBuiltinClassifyType(Result))