Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 163480)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -1779,6 +1779,8 @@
 def err_cconv_change : Error<
   "function declared '%0' here was previously declared "
   "%select{'%2'|without calling convention}1">;
+def warn_cconv_ignored : Warning<
+  "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>;
 def err_cconv_knr : Error<
   "function with no prototype cannot use %0 calling convention">;
 def err_cconv_varargs : Error<
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 163480)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -2221,7 +2221,8 @@
   void checkUnusedDeclAttributes(Declarator &D);
 
   bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
-  bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC);
+  bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
+                            QualType Type);
   bool CheckNoReturnAttr(const AttributeList &attr);
 
   /// \brief Stmt attributes - this routine is the top level dispatcher.
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp	(revision 163480)
+++ lib/Sema/SemaDeclAttr.cpp	(working copy)
@@ -3547,7 +3547,7 @@
   // Diagnostic is emitted elsewhere: here we store the (valid) Attr
   // in the Decl node for syntactic reasoning, e.g., pretty-printing.
   CallingConv CC;
-  if (S.CheckCallingConvAttr(Attr, CC))
+  if (S.CheckCallingConvAttr(Attr, CC, cast<ValueDecl>(D)->getType()))
     return;
 
   if (!isa<ObjCMethodDecl>(D)) {
@@ -3597,7 +3597,8 @@
   D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
 }
 
-bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
+bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
+                                QualType Type) {
   if (attr.isInvalid())
     return true;
 
@@ -3642,6 +3643,30 @@
   default: llvm_unreachable("unexpected attribute kind");
   }
 
+  // stdcall, thiscall, pascal and fastcall only apply to x86 architectures,
+  // and Pcs only applies to ARM.  So if the calling convention does not make
+  // sense for the target achitecture, we will ignore the calling convention
+  // entirely, and warn the user.
+  //
+  // FIXME: By changing the calling convention away from what was specified, 
+  // we make it impossible to perform rewrites. We should retain the original
+  // spelling of the attribute at some point.
+  llvm::Triple T = Context.getTargetInfo().getTriple();
+  bool Ignore = false;
+  if (attr.getKind() == AttributeList::AT_Pcs)
+    Ignore = T.getArch() != llvm::Triple::arm;
+  else if (attr.getKind() != AttributeList::AT_CDecl)
+    Ignore = T.getArch() != llvm::Triple::x86;
+
+  // If the type is not a function type, we emit a diagnostic as part of
+  // TypeProcessingState::diagnoseBadTypeAttribute.  We don't want to warn 
+  // about ignoring the calling convention when it's an error to apply the
+  // convention in the first place.
+  if (Ignore && Type->isFunctionType()) {
+    Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
+    CC = CC_Default;
+  }
+
   return false;
 }
 
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp	(revision 163480)
+++ lib/Sema/SemaType.cpp	(working copy)
@@ -3880,7 +3880,7 @@
 
   // Otherwise, a calling convention.
   CallingConv CC;
-  if (S.CheckCallingConvAttr(attr, CC))
+  if (S.CheckCallingConvAttr(attr, CC, type))
     return true;
 
   // Delay if the type didn't work out to a function.
Index: test/CodeGen/microsoft-call-conv.c
===================================================================
--- test/CodeGen/microsoft-call-conv.c	(revision 163480)
+++ test/CodeGen/microsoft-call-conv.c	(working copy)
@@ -1,22 +1,29 @@
 // RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -fms-compatibility -emit-llvm < %s | FileCheck -check-prefix X64 %s
 
 void __fastcall f1(void);
 void __stdcall f2(void);
 void __thiscall f3(void);
 void __fastcall f4(void) {
 // CHECK: define x86_fastcallcc void @f4()
+// X64: define void @f4()
   f1();
 // CHECK: call x86_fastcallcc void @f1()
+// X64: call void @f1()
 }
 void __stdcall f5(void) {
 // CHECK: define x86_stdcallcc void @f5()
+// X64: define void @f5()
   f2();
 // CHECK: call x86_stdcallcc void @f2()
+// X64: call void @f2()
 }
 void __thiscall f6(void) {
 // CHECK: define x86_thiscallcc void @f6()
+// X64: define void @f6()
   f3();
 // CHECK: call x86_thiscallcc void @f3()
+// X64: call void @f3
 }
 
 // PR5280
@@ -32,6 +39,7 @@
     // CHECK: call x86_fastcallcc void @f4()
     // CHECK: call x86_stdcallcc void @f5()
     // CHECK: call x86_thiscallcc void @f6()
+    // X64: call void @f5()
     pf1(); pf2(); pf3(); pf4(); pf5(); pf6();
     // CHECK: call x86_fastcallcc void %{{.*}}()
     // CHECK: call x86_stdcallcc void %{{.*}}()
Index: test/CodeGenCXX/mangle-ms.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms.cpp	(revision 163480)
+++ test/CodeGenCXX/mangle-ms.cpp	(working copy)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-compatibility -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
 
 // CHECK: @"\01?a@@3HA"
 // CHECK: @"\01?b@N@@3HA"
@@ -109,6 +110,7 @@
 }
 
 // CHECK: @"\01?alpha@@YGXMN@Z"
+// X64: @"\01?alpha@@YAXMN@Z"
 
 // Make sure tag-type mangling works.
 void gamma(class foo, struct bar, union baz, enum quux) {}
Index: test/Sema/callingconv.c
===================================================================
--- test/Sema/callingconv.c	(revision 163480)
+++ test/Sema/callingconv.c	(working copy)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -triple i386-unknown-unknown -verify
 
 void __attribute__((fastcall)) foo(float *a) { 
 }
@@ -40,8 +40,9 @@
 int __attribute__((pcs())) pcs2(void); // expected-error {{attribute takes one argument}}
 int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{attribute takes one argument}}
 int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires parameter 1 to be a string}}
-int __attribute__((pcs("aapcs"))) pcs5(void); // no-error
-int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // no-error
+/* These are ignored because the target is i386 and not ARM */
+int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{calling convention 'pcs' ignored for this target}}
+int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{calling convention 'pcs' ignored for this target}}
 int __attribute__((pcs("foo"))) pcs7(void); // expected-error {{Invalid PCS type}}
 
 // PR6361
Index: test/Sema/MicrosoftCompatibility-x64.c
===================================================================
--- test/Sema/MicrosoftCompatibility-x64.c	(revision 0)
+++ test/Sema/MicrosoftCompatibility-x64.c	(working copy)
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -triple x86_64-pc-win32
+int __stdcall f(void); /* expected-warning {{calling convention '__stdcall' ignored for this target}} */
+
+/* This should compile without warning because __stdcall is treated
+as __cdecl in MS compatibility mode for x64 compiles*/
+int __cdecl f(void) {
+  return 0;
+}
Index: test/Sema/MicrosoftCompatibility.c
===================================================================
--- test/Sema/MicrosoftCompatibility.c	(revision 163480)
+++ test/Sema/MicrosoftCompatibility.c	(working copy)
@@ -18,4 +18,10 @@
 __declspec(align(32768)) struct S1 { int a; } s;	/* expected-error {{requested alignment must be 8192 bytes or smaller}} */
 struct __declspec(aligned) S2 {}; /* expected-warning {{unknown __declspec attribute 'aligned' ignored}} */
 
-struct __declspec(appdomain) S3 {}; /* expected-warning {{__declspec attribute 'appdomain' is not supported}} */
\ No newline at end of file
+struct __declspec(appdomain) S3 {}; /* expected-warning {{__declspec attribute 'appdomain' is not supported}} */
+
+int __stdcall f(void); /* expected-note {{previous declaration is here}} */
+
+int __cdecl f(void) { /* expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}} */
+  return 0;
+}
Index: test/Sema/stdcall-fastcall-x64.c
===================================================================
--- test/Sema/stdcall-fastcall-x64.c	(revision 0)
+++ test/Sema/stdcall-fastcall-x64.c	(working copy)
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-linux-gnu %s
+
+// CC qualifier can be applied only to functions
+int __attribute__((stdcall)) var1; // expected-warning{{'stdcall' only applies to function types; type here is 'int'}}
+int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' only applies to function types; type here is 'int'}}
+
+// Different CC qualifiers are not compatible
+void __attribute__((stdcall, fastcall)) foo3(void); // expected-warning{{calling convention 'stdcall' ignored for this target}} expected-warning {{calling convention 'fastcall' ignored for this target}}
+void __attribute__((stdcall)) foo4(); // expected-warning{{calling convention 'stdcall' ignored for this target}}
+void __attribute__((fastcall)) foo4(void); // expected-warning {{calling convention 'fastcall' ignored for this target}}
+
+// rdar://8876096
+void rdar8876096foo1(int i, int j) __attribute__((fastcall, cdecl)); // expected-warning{{calling convention 'fastcall' ignored for this target}}
+void rdar8876096foo2(int i, int j) __attribute__((fastcall, stdcall)); // expected-warning{{calling convention 'stdcall' ignored for this target}} expected-warning {{calling convention 'fastcall' ignored for this target}}
+void rdar8876096foo3(int i, int j) __attribute__((fastcall, regparm(2))); // expected-warning {{calling convention 'fastcall' ignored for this target}}
+void rdar8876096foo4(int i, int j) __attribute__((stdcall, cdecl)); // expected-warning{{calling convention 'stdcall' ignored for this target}}
+void rdar8876096foo5(int i, int j) __attribute__((stdcall, fastcall)); // expected-warning{{calling convention 'stdcall' ignored for this target}} expected-warning {{calling convention 'fastcall' ignored for this target}}
+void rdar8876096foo6(int i, int j) __attribute__((cdecl, fastcall)); // expected-warning {{calling convention 'fastcall' ignored for this target}}
+void rdar8876096foo7(int i, int j) __attribute__((cdecl, stdcall)); // expected-warning{{calling convention 'stdcall' ignored for this target}}
+void rdar8876096foo8(int i, int j) __attribute__((regparm(2), fastcall)); // expected-warning {{calling convention 'fastcall' ignored for this target}}
Index: test/Sema/stdcall-fastcall.c
===================================================================
--- test/Sema/stdcall-fastcall.c	(revision 163480)
+++ test/Sema/stdcall-fastcall.c	(working copy)
@@ -1,4 +1,3 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-linux-gnu %s
 // RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin10 %s
 
 // CC qualifier can be applied only to functions
