]> granicus.if.org Git - clang/commitdiff
-fms-extensions: Add __va_start builtin, which is used for x64
authorReid Kleckner <reid@kleckner.net>
Wed, 26 Mar 2014 15:38:33 +0000 (15:38 +0000)
committerReid Kleckner <reid@kleckner.net>
Wed, 26 Mar 2014 15:38:33 +0000 (15:38 +0000)
The main difference between __va_start and __builtin_va_start is that
the address of the va_list has already been taken, and the va_list is
always a char*.

__va_end and __va_arg are not needed.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204821 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Builtins.def
lib/CodeGen/CGBuiltin.cpp
lib/Sema/SemaChecking.cpp
test/Sema/MicrosoftExtensions.c

index 53bec2ab83a91e188cfb073064400123c0ee767b..540ec25bad4541e5514f901dca8d66fe3ffa6c7b 100644 (file)
@@ -681,6 +681,7 @@ LANGBUILTIN(_alloca,      "v*z", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__assume,     "vb",  "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__noop,       "v.",  "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__debugbreak, "v",   "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__va_start,   "vc**.", "nt", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
index c105d80bf79e04be14df7ed7bf6b0c3c4d34e853..b0e63b647d885daa40fabb008be2ecaa618c25be 100644 (file)
@@ -215,8 +215,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
     return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0));
   case Builtin::BI__builtin_stdarg_start:
   case Builtin::BI__builtin_va_start:
+  case Builtin::BI__va_start:
   case Builtin::BI__builtin_va_end: {
-    Value *ArgValue = EmitVAListRef(E->getArg(0));
+    Value *ArgValue = (BuiltinID == Builtin::BI__va_start)
+                          ? EmitScalarExpr(E->getArg(0))
+                          : EmitVAListRef(E->getArg(0));
     llvm::Type *DestType = Int8PtrTy;
     if (ArgValue->getType() != DestType)
       ArgValue = Builder.CreateBitCast(ArgValue, DestType,
index 028523130560b1fe5884d5f43887d0274ad10238..f0e93a78f7581dcef30fb5e74fb37b54f2a7fdfd 100644 (file)
@@ -142,6 +142,7 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
     break;
   case Builtin::BI__builtin_stdarg_start:
   case Builtin::BI__builtin_va_start:
+  case Builtin::BI__va_start:
     if (SemaBuiltinVAStart(TheCall))
       return ExprError();
     break;
index 4441f179736359a0ca2dc28a390b931b9b1fd873..a4afcb1e640ffd56aedb8cf68ac68edc71b681bd 100644 (file)
@@ -131,3 +131,17 @@ int *(__ptr32 __sptr wrong9); // expected-error {{'__sptr' attribute only applie
 
 typedef int *T;
 T __ptr32 wrong10; // expected-error {{'__ptr32' attribute only applies to pointer arguments}}
+
+typedef char *my_va_list;
+void __cdecl __va_start(my_va_list *ap, ...); // expected-note {{passing argument to parameter 'ap' here}}
+void vmyprintf(const char *f, my_va_list ap);
+void myprintf(const char *f, ...) {
+  my_va_list ap;
+  if (1) {
+    __va_start(&ap, f);
+    vmyprintf(f, ap);
+    ap = 0;
+  } else {
+    __va_start(ap, f); // expected-warning {{incompatible pointer types passing 'my_va_list'}}
+  }
+}