Sema: Support for #pragma options align={reset,natural}. '#pragma options align'
shares the stack with '#pragma pack', who knew!?

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104786 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 1b61800..da3937f 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -4015,6 +4015,11 @@
                                                 MultiExprArg Args);
 
 
+  /// ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
+  virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
+                                       SourceLocation PragmaLoc,
+                                       SourceLocation KindLoc);
+
   /// ActOnPragmaPack - Called on well formed #pragma pack(...).
   virtual void ActOnPragmaPack(PragmaPackKind Kind,
                                IdentifierInfo *Name,
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index dc7815f..770bd21 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -18,7 +18,7 @@
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
-// Pragma Packed
+// Pragma 'pack' and 'options align'
 //===----------------------------------------------------------------------===//
 
 namespace {
@@ -94,6 +94,41 @@
   return 0;
 }
 
+void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
+                                   SourceLocation PragmaLoc,
+                                   SourceLocation KindLoc) {
+  if (PackContext == 0)
+    PackContext = new PragmaPackStack();
+
+  PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
+
+  // Reset just pops the top of the stack.
+  if (Kind == Action::POAK_Reset) {
+    // Do the pop.
+    if (!Context->pop(0)) {
+      // If a name was specified then failure indicates the name
+      // wasn't found. Otherwise failure indicates the stack was
+      // empty.
+      Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
+        << "stack empty";
+    }
+    return;
+  }
+
+  // We don't support #pragma options align=power.
+  switch (Kind) {
+  case POAK_Natural:
+    Context->push(0);
+    Context->setAlignment(0);
+    break;
+
+  default:
+    Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option)
+      << KindLoc;
+    break;
+  }
+}
+
 void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
                            ExprTy *alignment, SourceLocation PragmaLoc,
                            SourceLocation LParenLoc, SourceLocation RParenLoc) {