Handle "#pragma GCC visibility" in a few more places.  Switch over "#pragma pack" to use the same handling that gcc does.  Fixes <rdar://problem/10871094> and <rdar://problem/10893316>.

(Hopefully, common usage of these pragmas isn't irregular enough to break our current handling.  Doug has ideas for a more crazy approach if necessary.)

llvm-svn: 151307
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 433c76b..96a4f3a 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -37,6 +37,24 @@
   Actions.ActOnPragmaVisibility(VisType, VisLoc);
 }
 
+struct PragmaPackInfo {
+  Sema::PragmaPackKind Kind;
+  IdentifierInfo *Name;
+  Expr *Alignment;
+  SourceLocation LParenLoc;
+  SourceLocation RParenLoc;
+};
+
+void Parser::HandlePragmaPack() {
+  assert(Tok.is(tok::annot_pragma_pack));
+  PragmaPackInfo *Info =
+    static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
+  SourceLocation PragmaLoc = ConsumeToken();
+  Actions.ActOnPragmaPack(Info->Kind, Info->Name, Info->Alignment, PragmaLoc,
+                          Info->LParenLoc, Info->RParenLoc);
+  delete Info;
+}
+
 // #pragma GCC visibility comes in two variants:
 //   'push' '(' [visibility] ')'
 //   'pop'
@@ -196,8 +214,20 @@
     return;
   }
 
-  Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
-                          LParenLoc, RParenLoc);
+  PragmaPackInfo *Info = new PragmaPackInfo;
+  Info->Kind = Kind;
+  Info->Name = Name;
+  Info->Alignment = Alignment.release();
+  Info->LParenLoc = LParenLoc;
+  Info->RParenLoc = RParenLoc;
+
+  Token *Toks = new Token[1];
+  Toks[0].startToken();
+  Toks[0].setKind(tok::annot_pragma_pack);
+  Toks[0].setLocation(PackLoc);
+  Toks[0].setAnnotationValue(static_cast<void*>(Info));
+  PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
+                      /*OwnsTokens=*/true);
 }
 
 // #pragma ms_struct on