This update constitutes a significant re-write of the previous version of the 
patch.
  The unified MS-pragma handler has been updated to consume the token stream 
for the pragma up to eod and attach it to the annotation token, capped with an 
eof.  The parser inserts the tokens back into the stream and parses them.
  PragmaStack has been templated for future unification with the stack used by 
pragma pack.

Hi rsmith, majnemer, rnk,

http://llvm-reviews.chandlerc.com/D3065

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D3065?vs=7787&id=8116#toc

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/TokenKinds.def
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/CodeGen/CodeGenModule.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParsePragma.cpp
  lib/Parse/ParseStmt.cpp
  lib/Parse/Parser.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaAttr.cpp
  lib/Sema/SemaDecl.cpp
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -1716,6 +1716,24 @@
   let Documentation = [MSInheritanceDocs];
 }
 
+def MSSegment : Attr {
+  // This attribute has no spellings as it is only ever created implicitly.
+  let Spellings = [];
+  let Args = [StringArgument<"SegName">, UnsignedArgument<"kind">];
+
+  let AdditionalMembers = [{
+  enum Kind {
+    DataSeg,
+    BSSSeg,
+    ConstSeg,
+    CodeSeg
+  };
+
+  Kind getSegKind() const { return Kind(kind); }
+  }];
+  let Documentation = [Undocumented];
+}
+
 def MSVtorDisp : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -771,6 +771,8 @@
   "missing ')' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_expected_identifier : Warning<
   "expected identifier in '#pragma %0' - ignored">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_string : Warning<
+  "expected string literal in '#pragma %0' - ignored">, InGroup<IgnoredPragmas>;
 def warn_pragma_expected_integer : Warning<
   "expected integer between %0 and %1 inclusive in '#pragma %2' - ignored">,
   InGroup<IgnoredPragmas>;
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def
+++ include/clang/Basic/TokenKinds.def
@@ -684,6 +684,11 @@
 // handles them.
 ANNOTATION(pragma_ms_vtordisp)
 
+// Annotation for all microsoft #pragmas...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pragma)
+
 // Annotation for #pragma OPENCL EXTENSION...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h
+++ include/clang/Parse/Parser.h
@@ -154,6 +154,10 @@
   std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
   std::unique_ptr<PragmaHandler> MSPointersToMembers;
   std::unique_ptr<PragmaHandler> MSVtorDisp;
+  std::unique_ptr<PragmaHandler> MSDataSeg;
+  std::unique_ptr<PragmaHandler> MSBSSSeg;
+  std::unique_ptr<PragmaHandler> MSConstSeg;
+  std::unique_ptr<PragmaHandler> MSCodeSeg;
 
   std::unique_ptr<CommentHandler> CommentSemaHandler;
 
@@ -475,6 +479,8 @@
 
   void HandlePragmaMSVtorDisp();
 
+  void HandlePragmaMSPragma();
+
   /// \brief Handle the annotation token produced for
   /// #pragma align...
   void HandlePragmaAlign();
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -274,6 +274,15 @@
     PVDK_Reset          ///< #pragma vtordisp()
   };
 
+  enum PragmaMsStackAction {
+    PSK_Reset,    // #pragma ()
+    PSK_Set,      // #pragma ("name")
+    PSK_Push,     // #pragma (push[, id])
+    PSK_Push_Set, // #pragma (push[, id], "name")
+    PSK_Pop,      // #pragma (pop[, id])
+    PSK_Pop_Set,  // #pragma (pop[, id], "name")
+  };
+
   /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft
   /// C++ ABI.  Possible values are 0, 1, and 2, which mean:
   ///
@@ -289,6 +298,30 @@
   /// \brief Source location for newly created implicit MSInheritanceAttrs
   SourceLocation ImplicitMSInheritanceAttrLoc;
 
+  template<typename ValueType>
+  struct PragmaStack {
+    struct Slot {
+      llvm::StringRef StackSlotLabel;
+      ValueType Value;
+      SourceLocation PragmaLocation;
+    };
+    void Act(SourceLocation PragmaLocation,
+             PragmaMsStackAction Action,
+             llvm::StringRef StackSlotLabel,
+             ValueType Value);
+    explicit PragmaStack(const ValueType& Value)
+      : CurrentValue(Value) {}
+    SmallVector<Slot, 2> Stack;
+    ValueType CurrentValue;
+    SourceLocation CurrentPragmaLocation;
+  };
+  // FIXME: We should serialize / deserialize these if they occur in a PCH (but
+  // we shouldn't do so if they're in a module).
+  PragmaStack<StringLiteral *> DataSegStack;
+  PragmaStack<StringLiteral *> BSSSegStack;
+  PragmaStack<StringLiteral *> ConstSegStack;
+  PragmaStack<StringLiteral *> CodeSegStack;
+
   /// VisContext - Manages the stack for \#pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
@@ -7030,6 +7063,30 @@
   void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc,
                              MSVtorDispAttr::Mode Value);
 
+  /// \brief Called on well formed \#pragma data_seg().
+  void ActOnPragmaMSDataSeg(SourceLocation PragmaLocation,
+                            PragmaMsStackAction Action,
+                            llvm::StringRef StackSlotLabel,
+                            StringLiteral *SegmentName);
+
+  /// \brief Called on well formed \#pragma bss_seg().
+  void ActOnPragmaMSBSSSeg(SourceLocation PragmaLocation,
+                          PragmaMsStackAction Action,
+                          llvm::StringRef StackSlotLabel,
+                          StringLiteral *SegmentName);
+
+  /// \brief Called on well formed \#pragma const_seg().
+  void ActOnPragmaMSConstSeg(SourceLocation PragmaLocation,
+                             PragmaMsStackAction Action,
+                             llvm::StringRef StackSlotLabel,
+                             StringLiteral *SegmentName);
+
+  /// \brief Called on well formed \#pragma code_seg().
+  void ActOnPragmaMSCodeSeg(SourceLocation PragmaLocation,
+                            PragmaMsStackAction Action,
+                            llvm::StringRef StackSlotLabel,
+                            StringLiteral *SegmentName);
+
   /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
   void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
 
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -704,6 +704,9 @@
   if (const SectionAttr *SA = D->getAttr<SectionAttr>())
     GV->setSection(SA->getName());
 
+  if (D->hasAttr<MSSegmentAttr>())
+    GV->setSection(D->getAttr<MSSegmentAttr>()->getSegName());
+
   // Alias cannot have attributes. Filter them here.
   if (!isa<llvm::GlobalAlias>(GV))
     getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this);
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -2646,6 +2646,11 @@
         continue;
       }
 
+      if (Tok.is(tok::annot_pragma_ms_pragma)) {
+        HandlePragmaMSPragma();
+        continue;
+      }
+
       // If we see a namespace here, a close brace was missing somewhere.
       if (Tok.is(tok::kw_namespace)) {
         DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
Index: lib/Parse/ParsePragma.cpp
===================================================================
--- lib/Parse/ParsePragma.cpp
+++ lib/Parse/ParsePragma.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "RAIIObjectsForParser.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
@@ -124,6 +125,12 @@
                     Token &FirstToken) override;
 };
 
+struct PragmaMSPragma : public PragmaHandler {
+  explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
+  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+    Token &FirstToken);
+};
+
 }  // end namespace
 
 void Parser::initializePragmaHandlers() {
@@ -175,6 +182,14 @@
     PP.AddPragmaHandler(MSPointersToMembers.get());
     MSVtorDisp.reset(new PragmaMSVtorDisp());
     PP.AddPragmaHandler(MSVtorDisp.get());
+    MSDataSeg.reset(new PragmaMSPragma("data_seg"));
+    PP.AddPragmaHandler(MSDataSeg.get());
+    MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
+    PP.AddPragmaHandler(MSBSSSeg.get());
+    MSConstSeg.reset(new PragmaMSPragma("const_seg"));
+    PP.AddPragmaHandler(MSConstSeg.get());
+    MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
+    PP.AddPragmaHandler(MSCodeSeg.get());
   }
 }
 
@@ -214,6 +229,14 @@
     MSPointersToMembers.reset();
     PP.RemovePragmaHandler(MSVtorDisp.get());
     MSVtorDisp.reset();
+    PP.RemovePragmaHandler(MSDataSeg.get());
+    MSDataSeg.reset();
+    PP.RemovePragmaHandler(MSBSSSeg.get());
+    MSBSSSeg.reset();
+    PP.RemovePragmaHandler(MSConstSeg.get());
+    MSConstSeg.reset();
+    PP.RemovePragmaHandler(MSCodeSeg.get());
+    MSCodeSeg.reset();
   }
 
   PP.RemovePragmaHandler("STDC", FPContractHandler.get());
@@ -400,6 +423,96 @@
   Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
 }
 
+void Parser::HandlePragmaMSPragma() {
+  assert(Tok.is(tok::annot_pragma_ms_pragma));
+  // Grab the tokens out of the annotation and enter them into the stream.
+  auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue();
+  PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true);
+  SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
+  assert(Tok.isAnyIdentifier());
+  llvm::StringRef PragmaName = Tok.getIdentifierInfo()->getName();
+  // Note! BalancedDelimiterTracker throws an error if it fails to match
+  // correctly.  This is different than MSVCs behvaior that malformed pragmas
+  // are ignored with a warning.
+  BalancedDelimiterTracker Parens(*this, tok::l_paren, tok::eof);
+  PP.Lex(Tok); // pragma kind
+  // Figure out which #pragma we're dealing with.  The switch has no default
+  // because lex shouldn't emit the annotation token for unrecognized pragmas.
+  enum PragmaMSKind { DataSeg, BSSSeg, ConstSeg, CodeSeg } Kind =
+    llvm::StringSwitch<PragmaMSKind>(PragmaName)
+      .Case("data_seg", DataSeg)
+      .Case("bss_seg", BSSSeg)
+      .Case("const_seg", ConstSeg)
+      .Case("code_seg", CodeSeg);
+  llvm::StringRef SlotLabel;
+  if (Parens.consumeOpen())
+    goto ERROR_RETURN;
+  Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
+  if (Tok.isAnyIdentifier()) {
+    llvm::StringRef PushPop = Tok.getIdentifierInfo()->getName();
+    if (PushPop == "push")
+      Action = Sema::PSK_Push;
+    else if (PushPop == "pop")
+      Action = Sema::PSK_Pop;
+    else {
+      PP.Diag(PragmaLoc, diag::warn_pragma_invalid_action) << PragmaName;
+      goto ERROR_RETURN;
+    }
+    if (Action != Sema::PSK_Reset) {
+      PP.Lex(Tok); // push | pop
+      if (Tok.is(tok::comma)) {
+        PP.Lex(Tok); // ,
+        // If we've got a comma, we either need a 
+        if (Tok.isAnyIdentifier()) {
+          SlotLabel = Tok.getIdentifierInfo()->getName();
+          PP.Lex(Tok); // identifier
+          if (Tok.is(tok::comma))
+            PP.Lex(Tok);
+          else if (Tok.isNot(tok::r_paren)) {
+            PP.Diag(PragmaLoc, diag::warn_pragma_expected_punc) << PragmaName;
+            goto ERROR_RETURN;
+          }
+        }
+      } else if (Tok.isNot(tok::r_paren)) {
+        PP.Diag(PragmaLoc, diag::warn_pragma_expected_punc) << PragmaName;
+        goto ERROR_RETURN;
+      }
+    }
+  }
+  // Grab the string literal for our section name.
+  StringLiteral *SegmentName = nullptr;
+  if (Tok.isNot(tok::r_paren)) {
+    ExprResult SegmentNameExpr = ParseStringLiteralExpression();
+    if (SegmentNameExpr.isInvalid()) {
+      PP.Diag(PragmaLoc, diag::warn_pragma_expected_string) << PragmaName;
+      goto ERROR_RETURN;
+    }
+    SegmentName = cast<StringLiteral>(SegmentNameExpr.get());
+    // Setting section "" has no effect
+    if (SegmentName->getLength())
+      Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
+  }
+  if (Parens.consumeClose())
+    goto ERROR_RETURN;
+  if (Tok.isNot(tok::eof)) {
+    PP.Diag(PragmaLoc, diag::warn_pragma_extra_tokens_at_eol) << PragmaName;
+    goto ERROR_RETURN;
+  }
+  PP.Lex(Tok); // eof
+  if (Kind == DataSeg)
+    Actions.ActOnPragmaMSDataSeg(PragmaLoc, Action, SlotLabel, SegmentName);
+  else if (Kind == BSSSeg)
+    Actions.ActOnPragmaMSBSSSeg(PragmaLoc, Action, SlotLabel, SegmentName);
+  else if (Kind == ConstSeg)
+    Actions.ActOnPragmaMSConstSeg(PragmaLoc, Action, SlotLabel, SegmentName);
+  else if (Kind == CodeSeg)
+    Actions.ActOnPragmaMSCodeSeg(PragmaLoc, Action, SlotLabel, SegmentName);
+  return;
+ERROR_RETURN:
+  SkipUntil(tok::eof);
+  PP.Lex(Tok); // tok::eof
+}
+
 // #pragma GCC visibility comes in two variants:
 //   'push' '(' [visibility] ')'
 //   'pop'
@@ -1204,6 +1317,33 @@
   PP.EnterToken(AnnotTok);
 }
 
+/// \brief Handle all MS pragmas.  Simply forwards the tokens after inserting
+/// an annotation token.
+void PragmaMSPragma::HandlePragma(Preprocessor &PP,
+                                  PragmaIntroducerKind Introducer,
+                                  Token &Tok) {
+  Token EoF, AnnotTok;
+  EoF.startToken();
+  EoF.setKind(tok::eof);
+  AnnotTok.startToken();
+  AnnotTok.setKind(tok::annot_pragma_ms_pragma);
+  AnnotTok.setLocation(Tok.getLocation());
+  SmallVector<Token, 8> TokenVector;
+  // Suck up all of the tokens before the eod.
+  for (; Tok.isNot(tok::eod); PP.Lex(Tok))
+    TokenVector.push_back(Tok);
+  // Add a sentinal EoF token to the end of the list.
+  TokenVector.push_back(EoF);
+  // We must allocate this array with new because EnterTokenStream is going to
+  // delete it later.
+  Token *TokenArray = new Token[TokenVector.size()];
+  memcpy(TokenArray, TokenVector.data(), sizeof(Token) * TokenVector.size());
+  auto Value = new (PP.getPreprocessorAllocator())
+      std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size()));
+  AnnotTok.setAnnotationValue(Value);
+  PP.EnterToken(AnnotTok);
+}
+
 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
 ///
 /// The syntax is:
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp
+++ lib/Parse/ParseStmt.cpp
@@ -350,6 +350,10 @@
     HandlePragmaMSPointersToMembers();
     return StmtEmpty();
 
+  case tok::annot_pragma_ms_pragma:
+    ProhibitAttributes(Attrs);
+    HandlePragmaMSPragma();
+    return StmtEmpty();
   }
 
   // If we reached this code, the statement must end in a semicolon.
@@ -828,6 +832,9 @@
     case tok::annot_pragma_ms_pointers_to_members:
       HandlePragmaMSPointersToMembers();
       break;
+    case tok::annot_pragma_ms_pragma:
+      HandlePragmaMSPragma();
+      break;
     default:
       checkForPragmas = false;
       break;
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp
+++ lib/Parse/Parser.cpp
@@ -631,6 +631,9 @@
   case tok::annot_pragma_ms_vtordisp:
     HandlePragmaMSVtorDisp();
     return DeclGroupPtrTy();
+  case tok::annot_pragma_ms_pragma:
+    HandlePragmaMSPragma();
+    return DeclGroupPtrTy();
   case tok::semi:
     // Either a C++11 empty-declaration or attribute-declaration.
     SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -79,7 +79,8 @@
     MSPointerToMemberRepresentationMethod(
         LangOpts.getMSPointerToMemberRepresentationMethod()),
     VtorDispModeStack(1, MSVtorDispAttr::Mode(LangOpts.VtorDispMode)),
-    VisContext(0),
+    DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
+    CodeSegStack(nullptr), VisContext(0),
     IsBuildingRecoveryCallExpr(false),
     ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
     IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
Index: lib/Sema/SemaAttr.cpp
===================================================================
--- lib/Sema/SemaAttr.cpp
+++ lib/Sema/SemaAttr.cpp
@@ -325,6 +325,102 @@
   }
 }
 
+template<typename Type> Type
+PopToName(std::vector<llvm::StringRef, Type>& Stack, llvm::StringRef Key) {
+  if (!ActionTarget.empty()) {
+    auto I = std::find_if(DataSegStack.rbegin(), DataSegStack.rend(),
+      [&](const std::pair<llvm::StringRef, StringLiteral *> &x) {
+      return x.first == ActionTarget;
+    });
+    CurrentDataSegment = I->second;
+    if (I != DataSegStack.rend())
+      DataSegStack.erase(std::prev(I.base()), DataSegStack.end());
+  }
+  else if (!DataSegStack.empty()) {
+    CurrentDataSegment = DataSegStack.back().second;
+    DataSegStack.pop_back();
+  }
+}
+
+template<typename ValueType>
+void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
+                                       PragmaMsStackAction Action,
+                                       llvm::StringRef StackSlotLabel,
+                                       ValueType Value) {
+  if (Action == PSK_Reset) {
+    CurrentValue = nullptr;
+    return;
+  }
+  if (Action & PSK_Push)
+    Stack.push_back({StackSlotLabel, CurrentValue, CurrentPragmaLocation});
+  else if (Action & PSK_Pop) {
+    if (!StackSlotLabel.empty()) {
+      // If we've got a label, try to find it and jump there.
+      auto I = std::find_if(Stack.rbegin(), Stack.rend(),
+        [&](const Slot &x) { return x.StackSlotLabel == StackSlotLabel; });
+      // If we found the label so pop from there.
+      if (I != Stack.rend()) {
+        CurrentValue = I->Value;
+        CurrentPragmaLocation = I->PragmaLocation;
+        Stack.erase(std::prev(I.base()), Stack.end());
+      }
+    } else if (!Stack.empty()) {
+      // We don't have a label, just pop the last entry.
+      CurrentValue = Stack.back().Value;
+      CurrentPragmaLocation = Stack.back().PragmaLocation;
+      Stack.pop_back();
+    }
+  }
+  if (Action & PSK_Set) {
+    CurrentValue = Value;
+    CurrentPragmaLocation = PragmaLocation;
+  }
+}
+
+/// \brief Called on well formed \#pragma bss_seg().
+void Sema::ActOnPragmaMSBSSSeg(SourceLocation PragmaLocation,
+                               PragmaMsStackAction Action,
+                               llvm::StringRef StackSlotLabel,
+                               StringLiteral *SegmentName) {
+  if (Action & PSK_Pop && BSSSegStack.Stack.empty())
+    Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "bss_seg"
+    << "stack empty";
+  BSSSegStack.Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
+}
+
+/// \brief Called on well formed \#pragma data_seg().
+void Sema::ActOnPragmaMSDataSeg(SourceLocation PragmaLocation,
+                                PragmaMsStackAction Action,
+                                llvm::StringRef StackSlotLabel,
+                                StringLiteral *SegmentName) {
+  if (Action & PSK_Pop && DataSegStack.Stack.empty())
+    Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "data_seg"
+    << "stack empty";
+  DataSegStack.Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
+}
+
+/// \brief Called on well formed \#pragma bss_seg().
+void Sema::ActOnPragmaMSConstSeg(SourceLocation PragmaLocation,
+                                 PragmaMsStackAction Action,
+                                 llvm::StringRef StackSlotLabel,
+                                 StringLiteral *SegmentName) {
+  if (Action & PSK_Pop && ConstSegStack.Stack.empty())
+    Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "const_seg"
+    << "stack empty";
+  ConstSegStack.Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
+}
+
+/// \brief Called on well formed \#pragma code_seg().
+void Sema::ActOnPragmaMSCodeSeg(SourceLocation PragmaLocation,
+                                PragmaMsStackAction Action,
+                                llvm::StringRef StackSlotLabel,
+                                StringLiteral *SegmentName) {
+  if (Action & PSK_Pop && CodeSegStack.Stack.empty())
+    Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "code_seg"
+    << "stack empty";
+  CodeSegStack.Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
+}
+
 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
                              SourceLocation PragmaLoc) {
 
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -6974,6 +6974,11 @@
     NewFD->setInvalidDecl();
   }
 
+  if (D.isFunctionDefinition() && CodeSegStack.CurrentValue)
+    NewFD->addAttr(MSSegmentAttr::CreateImplicit(
+    Context, CodeSegStack.CurrentValue->getString(),
+    MSSegmentAttr::CodeSeg, CodeSegStack.CurrentPragmaLocation));
+
   // Handle attributes.
   ProcessDeclAttributes(S, NewFD, D);
 
@@ -8838,6 +8843,26 @@
       Diag(var->getLocation(), diag::note_use_thread_local);
   }
 
+  if (var->isThisDeclarationADefinition() &&
+      ActiveTemplateInstantiations.empty()) {
+    if (var->getType().isConstQualified()) {
+      if (ConstSegStack.CurrentValue)
+        var->addAttr(MSSegmentAttr::CreateImplicit(
+        Context, ConstSegStack.CurrentValue->getString(),
+        MSSegmentAttr::ConstSeg, ConstSegStack.CurrentPragmaLocation));
+    }
+    else if (!var->getInit()) {
+      if (BSSSegStack.CurrentValue)
+        var->addAttr(MSSegmentAttr::CreateImplicit(
+        Context, BSSSegStack.CurrentValue->getString(),
+        MSSegmentAttr::BSSSeg, BSSSegStack.CurrentPragmaLocation));
+    }
+    else if (DataSegStack.CurrentValue)
+      var->addAttr(MSSegmentAttr::CreateImplicit(
+      Context, DataSegStack.CurrentValue->getString(),
+      MSSegmentAttr::DataSeg, DataSegStack.CurrentPragmaLocation));
+  }
+
   // All the following checks are C++ only.
   if (!getLangOpts().CPlusPlus) return;
 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to