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;