Commit 1a711b16 authored by Reid Kleckner's avatar Reid Kleckner
Browse files

-fms-extensions: Implement half of #pragma init_seg

Summary:
This pragma is very rare.  We could *hypothetically* lower some uses of
it down to @llvm.global_ctors, but given that GlobalOpt isn't able to
optimize prioritized global ctors today, there's really no point.

If we wanted to do this in the future, I would check if the section used
in the pragma started with ".CRT$XC" and had up to two characters after
it.  Those two characters could form the 16-bit initialization priority
that we support in @llvm.global_ctors.  We would have to teach LLVM to
lower prioritized global ctors on COFF as well.

This should let us compile some silly uses of this pragma in WebKit /
Blink.

Reviewers: rsmith, majnemer

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D4549

llvm-svn: 213593
parent e1aaced0
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1767,6 +1767,18 @@ def MSVtorDisp : InheritableAttr {
  let Documentation = [Undocumented];
}

def InitSeg : Attr {
  let Spellings = [Pragma<"", "init_seg">];
  let Args = [StringArgument<"Section">];
  let SemaHandler = 0;
  let Documentation = [InitSegDocs];
  let AdditionalMembers = [{
  void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
    OS << '(' << getSection() << ')';
  }
  }];
}

def Unaligned : IgnoredAttr {
  let Spellings = [Keyword<"__unaligned">];
}
+16 −0
Original line number Diff line number Diff line
@@ -36,6 +36,22 @@ global variable or function should be in after translation.
  let Heading = "section (gnu::section, __declspec(allocate))";
}

def InitSegDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The attribute applied by ``pragma init_seg()`` controls the section into
which global initialization function pointers are emitted.  It is only
available with ``-fms-extensions``.  Typically, this function pointer is
emitted into ``.CRT$XCU`` on Windows.  The user can change the order of
initialization by using a different section name with the same
``.CRT$XC`` prefix and a suffix that sorts lexicographically before or
after the standard ``.CRT$XCU`` sections.  See the init_seg_
documentation on MSDN for more information.

.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx
  }];
}

def TLSModelDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
+3 −0
Original line number Diff line number Diff line
@@ -800,6 +800,9 @@ def warn_pragma_expected_section_push_pop_or_name : Warning<
def warn_pragma_expected_section_label_or_name : Warning<
  "expected a stack label or a string literal for the section name in '#pragma %0' - ignored">,
  InGroup<IgnoredPragmas>;
def warn_pragma_expected_init_seg : Warning<
  "expected 'compiler', 'lib', 'user', or a string literal for the section name 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>;
+1 −1
Original line number Diff line number Diff line
@@ -725,7 +725,7 @@ private:
  /// returned.
  bool ExpectAndConsume(tok::TokenKind ExpectedTok,
                        unsigned Diag = diag::err_expected,
                        const char *DiagMsg = "");
                        StringRef DiagMsg = "");

  /// \brief The parser expects a semicolon and, if present, will consume it.
  ///
+8 −0
Original line number Diff line number Diff line
@@ -330,6 +330,10 @@ public:
  PragmaStack<StringLiteral *> ConstSegStack;
  PragmaStack<StringLiteral *> CodeSegStack;

  /// Last section used with #pragma init_seg.
  StringLiteral *CurInitSeg;
  SourceLocation CurInitSegLoc;

  /// VisContext - Manages the stack for \#pragma GCC visibility.
  void *VisContext; // Really a "PragmaVisStack*"

@@ -7179,6 +7183,10 @@ public:
  void ActOnPragmaMSSection(SourceLocation PragmaLocation,
                            int SectionFlags, StringLiteral *SegmentName);

  /// \brief Called on well-formed \#pragma init_seg().
  void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
                            StringLiteral *SegmentName);

  /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
  void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);

Loading