Improves parsing and semantic analysis for MS __declspec attributes.  This includes support for the align (which fixes PR12631).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158717 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/ms-declspecs.c b/test/CodeGen/ms-declspecs.c
index d3235ae..91862a7 100644
--- a/test/CodeGen/ms-declspecs.c
+++ b/test/CodeGen/ms-declspecs.c
@@ -1,5 +1,13 @@
 // RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s
 
+struct __declspec(align(16)) S {
+  char x;
+};
+union { struct S s; } u;
+
+// CHECK: @u = {{.*}}zeroinitializer, align 16
+
+
 // CHECK: define void @t3() nounwind noinline naked {
 __declspec(naked) void t3() {}
 
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index c20bdb6..cd03ac8 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -3,10 +3,10 @@
 int __stdcall func();
 typedef int (__cdecl *tptr)();
 void (*__fastcall fastpfunc)();
-struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {};
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; /* expected-warning{{__declspec attribute 'novtable' is not supported}} */
 extern __declspec(dllimport) void __stdcall VarR4FromDec();
 __declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
-__declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory );
+__declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); /* expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
 typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
 
 void * __ptr64 PtrToPtr64(const void *p)
@@ -69,7 +69,7 @@
 [repeatable][source_annotation_attribute( Parameter|ReturnValue )]
 struct SA_Post{ SA_Post(); int attr; };
 
-[returnvalue:SA_Post( attr=1)] 
+[returnvalue:SA_Post( attr=1)]
 int foo1([SA_Post(attr=1)] void *param);
 
 
@@ -80,3 +80,25 @@
   __assume(a);
   __debugbreak();
 }
+
+struct __declspec(frobble) S1 {};	/* expected-warning {{unknown __declspec attribute 'frobble' ignored}} */
+struct __declspec(12) S2 {};	/* expected-error {{__declspec attributes must be an identifier or string literal}} */
+struct __declspec("testing") S3 {}; /* expected-warning {{__declspec attribute '"testing"' is not supported}} */
+
+/* Ensure multiple declspec attributes are supported */
+struct __declspec(align(8) deprecated) S4 {};
+
+/* But multiple declspecs must still be legal */
+struct __declspec(deprecated frobble "testing") S5 {};  /* expected-warning {{unknown __declspec attribute 'frobble' ignored}} expected-warning {{__declspec attribute '"testing"' is not supported}} */
+struct __declspec(unknown(12) deprecated) S6 {};	/* expected-warning {{unknown __declspec attribute 'unknown' ignored}}*/
+
+struct S7 {
+	int foo() { return 12; }
+	__declspec(property(get=foo) deprecated) int t;
+};
+
+/* Technically, this is legal (though it does nothing) */
+__declspec() void quux( void ) {
+  struct S7 s;
+  int i = s.t;	/* expected-warning {{'t' is deprecated}} */
+}
diff --git a/test/Sema/MicrosoftCompatibility.c b/test/Sema/MicrosoftCompatibility.c
index f148e86..6b137a6 100644
--- a/test/Sema/MicrosoftCompatibility.c
+++ b/test/Sema/MicrosoftCompatibility.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility
 
-enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}    
+enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
 enum ENUM1 var1 = 3;
 enum ENUM1* var2 = 0;
 
@@ -14,3 +14,8 @@
 __declspec(noreturn) void f6( void ) {
 	return;  // expected-warning {{function 'f6' declared 'noreturn' should not return}}
 }
+
+__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
diff --git a/test/Sema/MicrosoftExtensions.c b/test/Sema/MicrosoftExtensions.c
index 52cb882..7c2782f 100644
--- a/test/Sema/MicrosoftExtensions.c
+++ b/test/Sema/MicrosoftExtensions.c
@@ -93,6 +93,8 @@
 #define MY_TEXT		"This is also deprecated"
 __declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} // expected-note {{'Dfunc1' declared here}}
 
+struct __declspec(deprecated(123)) DS2 {};	// expected-error {{argument to deprecated attribute was not a string literal}}
+
 void test( void ) {
 	e1 = one;	// expected-warning {{'e1' is deprecated: This is deprecated}}
 	struct DS1 s = { 0 };	// expected-warning {{'DS1' is deprecated}}