Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/MC/MCParser/COFFAsmParser.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/ADT/StringRef.h"
10
#include "llvm/ADT/StringSwitch.h"
11
#include "llvm/ADT/Triple.h"
12
#include "llvm/ADT/Twine.h"
13
#include "llvm/BinaryFormat/COFF.h"
14
#include "llvm/MC/MCContext.h"
15
#include "llvm/MC/MCDirectives.h"
16
#include "llvm/MC/MCObjectFileInfo.h"
17
#include "llvm/MC/MCParser/MCAsmLexer.h"
18
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
19
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
20
#include "llvm/MC/MCRegisterInfo.h"
21
#include "llvm/MC/MCSectionCOFF.h"
22
#include "llvm/MC/MCStreamer.h"
23
#include "llvm/MC/SectionKind.h"
24
#include "llvm/Support/SMLoc.h"
25
#include <cassert>
26
#include <cstdint>
27
#include <limits>
28
#include <utility>
29
30
using namespace llvm;
31
32
namespace {
33
34
class COFFAsmParser : public MCAsmParserExtension {
35
  template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
36
12.9k
  void addDirectiveHandler(StringRef Directive) {
37
12.9k
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
12.9k
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
12.9k
    getParser().addDirectiveHandler(Directive, Handler);
40
12.9k
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSectionDirectiveText(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSectionDirectiveData(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSectionDirectiveBSS(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveSection(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveDef(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveScl(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveType(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveEndef(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveSecRel32(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveSymIdx(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveSafeSEH(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveSecIdx(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveLinkOnce(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveRVA(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveStartProc(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveEndProc(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveStartChained(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveEndChained(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveHandler(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveHandlerData(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectivePushReg(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveSetFrame(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveAllocStack(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveSaveReg(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveSaveXMM(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectivePushFrame(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseSEHDirectiveEndProlog(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
COFFAsmParser.cpp:void (anonymous namespace)::COFFAsmParser::addDirectiveHandler<&((anonymous namespace)::COFFAsmParser::ParseDirectiveSymbolAttribute(llvm::StringRef, llvm::SMLoc))>(llvm::StringRef)
Line
Count
Source
36
462
  void addDirectiveHandler(StringRef Directive) {
37
462
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38
462
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
39
462
    getParser().addDirectiveHandler(Directive, Handler);
40
462
  }
41
42
  bool ParseSectionSwitch(StringRef Section,
43
                          unsigned Characteristics,
44
                          SectionKind Kind);
45
46
  bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
47
                          SectionKind Kind, StringRef COMDATSymName,
48
                          COFF::COMDATType Type);
49
50
  bool ParseSectionName(StringRef &SectionName);
51
  bool ParseSectionFlags(StringRef SectionName, StringRef FlagsString,
52
                         unsigned *Flags);
53
54
462
  void Initialize(MCAsmParser &Parser) override {
55
462
    // Call the base implementation.
56
462
    MCAsmParserExtension::Initialize(Parser);
57
462
58
462
    addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
59
462
    addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
60
462
    addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
61
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
62
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
63
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
64
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
65
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
66
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
67
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymIdx>(".symidx");
68
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(".safeseh");
69
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
70
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
71
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveRVA>(".rva");
72
462
73
462
    // Win64 EH directives.
74
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
75
462
                                                                   ".seh_proc");
76
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
77
462
                                                                ".seh_endproc");
78
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
79
462
                                                           ".seh_startchained");
80
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
81
462
                                                             ".seh_endchained");
82
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
83
462
                                                                ".seh_handler");
84
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
85
462
                                                            ".seh_handlerdata");
86
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
87
462
                                                                ".seh_pushreg");
88
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
89
462
                                                               ".seh_setframe");
90
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
91
462
                                                             ".seh_stackalloc");
92
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
93
462
                                                                ".seh_savereg");
94
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
95
462
                                                                ".seh_savexmm");
96
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
97
462
                                                              ".seh_pushframe");
98
462
    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
99
462
                                                            ".seh_endprologue");
100
462
    addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
101
462
  }
102
103
270
  bool ParseSectionDirectiveText(StringRef, SMLoc) {
104
270
    return ParseSectionSwitch(".text",
105
270
                              COFF::IMAGE_SCN_CNT_CODE
106
270
                            | COFF::IMAGE_SCN_MEM_EXECUTE
107
270
                            | COFF::IMAGE_SCN_MEM_READ,
108
270
                              SectionKind::getText());
109
270
  }
110
111
53
  bool ParseSectionDirectiveData(StringRef, SMLoc) {
112
53
    return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
113
53
                                           COFF::IMAGE_SCN_MEM_READ |
114
53
                                           COFF::IMAGE_SCN_MEM_WRITE,
115
53
                              SectionKind::getData());
116
53
  }
117
118
23
  bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
119
23
    return ParseSectionSwitch(".bss",
120
23
                              COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
121
23
                            | COFF::IMAGE_SCN_MEM_READ
122
23
                            | COFF::IMAGE_SCN_MEM_WRITE,
123
23
                              SectionKind::getBSS());
124
23
  }
125
126
  bool ParseDirectiveSection(StringRef, SMLoc);
127
  bool ParseDirectiveDef(StringRef, SMLoc);
128
  bool ParseDirectiveScl(StringRef, SMLoc);
129
  bool ParseDirectiveType(StringRef, SMLoc);
130
  bool ParseDirectiveEndef(StringRef, SMLoc);
131
  bool ParseDirectiveSecRel32(StringRef, SMLoc);
132
  bool ParseDirectiveSecIdx(StringRef, SMLoc);
133
  bool ParseDirectiveSafeSEH(StringRef, SMLoc);
134
  bool ParseDirectiveSymIdx(StringRef, SMLoc);
135
  bool parseCOMDATType(COFF::COMDATType &Type);
136
  bool ParseDirectiveLinkOnce(StringRef, SMLoc);
137
  bool ParseDirectiveRVA(StringRef, SMLoc);
138
139
  // Win64 EH directives.
140
  bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
141
  bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
142
  bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
143
  bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
144
  bool ParseSEHDirectiveHandler(StringRef, SMLoc);
145
  bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
146
  bool ParseSEHDirectivePushReg(StringRef, SMLoc);
147
  bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
148
  bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
149
  bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
150
  bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
151
  bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
152
  bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
153
154
  bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
155
  bool ParseSEHRegisterNumber(unsigned &RegNo);
156
  bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
157
158
public:
159
462
  COFFAsmParser() = default;
160
};
161
162
} // end annonomous namespace.
163
164
706
static SectionKind computeSectionKind(unsigned Flags) {
165
706
  if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
166
166
    return SectionKind::getText();
167
540
  if (Flags & COFF::IMAGE_SCN_MEM_READ &&
168
540
      
(Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0530
)
169
354
    return SectionKind::getReadOnly();
170
186
  return SectionKind::getData();
171
186
}
172
173
bool COFFAsmParser::ParseSectionFlags(StringRef SectionName,
174
609
                                      StringRef FlagsString, unsigned *Flags) {
175
609
  enum {
176
609
    None        = 0,
177
609
    Alloc       = 1 << 0,
178
609
    Code        = 1 << 1,
179
609
    Load        = 1 << 2,
180
609
    InitData    = 1 << 3,
181
609
    Shared      = 1 << 4,
182
609
    NoLoad      = 1 << 5,
183
609
    NoRead      = 1 << 6,
184
609
    NoWrite     = 1 << 7,
185
609
    Discardable = 1 << 8,
186
609
  };
187
609
188
609
  bool ReadOnlyRemoved = false;
189
609
  unsigned SecFlags = None;
190
609
191
1.14k
  for (char FlagChar : FlagsString) {
192
1.14k
    switch (FlagChar) {
193
1.14k
    case 'a':
194
2
      // Ignored.
195
2
      break;
196
1.14k
197
1.14k
    case 'b': // bss section
198
8
      SecFlags |= Alloc;
199
8
      if (SecFlags & InitData)
200
2
        return TokError("conflicting section flags 'b' and 'd'.");
201
6
      SecFlags &= ~Load;
202
6
      break;
203
6
204
381
    case 'd': // data section
205
381
      SecFlags |= InitData;
206
381
      if (SecFlags & Alloc)
207
2
        return TokError("conflicting section flags 'b' and 'd'.");
208
379
      SecFlags &= ~NoWrite;
209
379
      if ((SecFlags & NoLoad) == 0)
210
379
        SecFlags |= Load;
211
379
      break;
212
379
213
379
    case 'n': // section is not loaded
214
8
      SecFlags |= NoLoad;
215
8
      SecFlags &= ~Load;
216
8
      break;
217
379
218
379
    case 'D': // discardable
219
2
      SecFlags |= Discardable;
220
2
      break;
221
379
222
523
    case 'r': // read-only
223
523
      ReadOnlyRemoved = false;
224
523
      SecFlags |= NoWrite;
225
523
      if ((SecFlags & Code) == 0)
226
367
        SecFlags |= InitData;
227
523
      if ((SecFlags & NoLoad) == 0)
228
523
        SecFlags |= Load;
229
523
      break;
230
379
231
379
    case 's': // shared section
232
3
      SecFlags |= Shared | InitData;
233
3
      SecFlags &= ~NoWrite;
234
3
      if ((SecFlags & NoLoad) == 0)
235
3
        SecFlags |= Load;
236
3
      break;
237
379
238
379
    case 'w': // writable
239
43
      SecFlags &= ~NoWrite;
240
43
      ReadOnlyRemoved = true;
241
43
      break;
242
379
243
379
    case 'x': // executable section
244
166
      SecFlags |= Code;
245
166
      if ((SecFlags & NoLoad) == 0)
246
166
        SecFlags |= Load;
247
166
      if (!ReadOnlyRemoved)
248
166
        SecFlags |= NoWrite;
249
166
      break;
250
379
251
379
    case 'y': // not readable
252
10
      SecFlags |= NoRead | NoWrite;
253
10
      break;
254
379
255
379
    default:
256
0
      return TokError("unknown flag");
257
1.14k
    }
258
1.14k
  }
259
609
260
609
  *Flags = 0;
261
605
262
605
  if (SecFlags == None)
263
32
    SecFlags = InitData;
264
605
265
605
  if (SecFlags & Code)
266
166
    *Flags |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE;
267
605
  if (SecFlags & InitData)
268
424
    *Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
269
605
  if ((SecFlags & Alloc) && 
(SecFlags & Load) == 04
)
270
4
    *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
271
605
  if (SecFlags & NoLoad)
272
8
    *Flags |= COFF::IMAGE_SCN_LNK_REMOVE;
273
605
  if ((SecFlags & Discardable) ||
274
605
      
MCSectionCOFF::isImplicitlyDiscardable(SectionName)603
)
275
190
    *Flags |= COFF::IMAGE_SCN_MEM_DISCARDABLE;
276
605
  if ((SecFlags & NoRead) == 0)
277
595
    *Flags |= COFF::IMAGE_SCN_MEM_READ;
278
605
  if ((SecFlags & NoWrite) == 0)
279
75
    *Flags |= COFF::IMAGE_SCN_MEM_WRITE;
280
605
  if (SecFlags & Shared)
281
3
    *Flags |= COFF::IMAGE_SCN_MEM_SHARED;
282
605
283
605
  return false;
284
609
}
285
286
/// ParseDirectiveSymbolAttribute
287
///  ::= { ".weak", ... } [ identifier ( , identifier )* ]
288
8
bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
289
8
  MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
290
8
    .Case(".weak", MCSA_Weak)
291
8
    .Default(MCSA_Invalid);
292
8
  assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
293
8
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
294
8
    while (true) {
295
8
      StringRef Name;
296
8
297
8
      if (getParser().parseIdentifier(Name))
298
0
        return TokError("expected identifier in directive");
299
8
300
8
      MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
301
8
302
8
      getStreamer().EmitSymbolAttribute(Sym, Attr);
303
8
304
8
      if (getLexer().is(AsmToken::EndOfStatement))
305
8
        break;
306
0
307
0
      if (getLexer().isNot(AsmToken::Comma))
308
0
        return TokError("unexpected token in directive");
309
0
      Lex();
310
0
    }
311
8
  }
312
8
313
8
  Lex();
314
8
  return false;
315
8
}
316
317
bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
318
                                       unsigned Characteristics,
319
346
                                       SectionKind Kind) {
320
346
  return ParseSectionSwitch(Section, Characteristics, Kind, "", (COFF::COMDATType)0);
321
346
}
322
323
bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
324
                                       unsigned Characteristics,
325
                                       SectionKind Kind,
326
                                       StringRef COMDATSymName,
327
1.05k
                                       COFF::COMDATType Type) {
328
1.05k
  if (getLexer().isNot(AsmToken::EndOfStatement))
329
0
    return TokError("unexpected token in section switching directive");
330
1.05k
  Lex();
331
1.05k
332
1.05k
  getStreamer().SwitchSection(getContext().getCOFFSection(
333
1.05k
      Section, Characteristics, Kind, COMDATSymName, Type));
334
1.05k
335
1.05k
  return false;
336
1.05k
}
337
338
712
bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
339
712
  if (!getLexer().is(AsmToken::Identifier))
340
0
    return true;
341
712
342
712
  SectionName = getTok().getIdentifier();
343
712
  Lex();
344
712
  return false;
345
712
}
346
347
// .section name [, "flags"] [, identifier [ identifier ], identifier]
348
//
349
// Supported flags:
350
//   a: Ignored.
351
//   b: BSS section (uninitialized data)
352
//   d: data section (initialized data)
353
//   n: "noload" section (removed by linker)
354
//   D: Discardable section
355
//   r: Readable section
356
//   s: Shared section
357
//   w: Writable section
358
//   x: Executable section
359
//   y: Not-readable section (clears 'r')
360
//
361
// Subsections are not supported.
362
712
bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
363
712
  StringRef SectionName;
364
712
365
712
  if (ParseSectionName(SectionName))
366
0
    return TokError("expected identifier in directive");
367
712
368
712
  unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
369
712
                   COFF::IMAGE_SCN_MEM_READ |
370
712
                   COFF::IMAGE_SCN_MEM_WRITE;
371
712
372
712
  if (getLexer().is(AsmToken::Comma)) {
373
609
    Lex();
374
609
375
609
    if (getLexer().isNot(AsmToken::String))
376
0
      return TokError("expected string in directive");
377
609
378
609
    StringRef FlagsStr = getTok().getStringContents();
379
609
    Lex();
380
609
381
609
    if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
382
4
      return true;
383
708
  }
384
708
385
708
  COFF::COMDATType Type = (COFF::COMDATType)0;
386
708
  StringRef COMDATSymName;
387
708
  if (getLexer().is(AsmToken::Comma)) {
388
275
    Type = COFF::IMAGE_COMDAT_SELECT_ANY;
389
275
    Lex();
390
275
391
275
    Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
392
275
393
275
    if (!getLexer().is(AsmToken::Identifier))
394
2
      return TokError("expected comdat type such as 'discard' or 'largest' "
395
2
                      "after protection bits");
396
273
397
273
    if (parseCOMDATType(Type))
398
0
      return true;
399
273
400
273
    if (getLexer().isNot(AsmToken::Comma))
401
0
      return TokError("expected comma in directive");
402
273
    Lex();
403
273
404
273
    if (getParser().parseIdentifier(COMDATSymName))
405
0
      return TokError("expected identifier in directive");
406
706
  }
407
706
408
706
  if (getLexer().isNot(AsmToken::EndOfStatement))
409
0
    return TokError("unexpected token in directive");
410
706
411
706
  SectionKind Kind = computeSectionKind(Flags);
412
706
  if (Kind.isText()) {
413
166
    const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
414
166
    if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
415
46
      Flags |= COFF::IMAGE_SCN_MEM_16BIT;
416
166
  }
417
706
  ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
418
706
  return false;
419
706
}
420
421
320
bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
422
320
  StringRef SymbolName;
423
320
424
320
  if (getParser().parseIdentifier(SymbolName))
425
0
    return TokError("expected identifier in directive");
426
320
427
320
  MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
428
320
429
320
  getStreamer().BeginCOFFSymbolDef(Sym);
430
320
431
320
  Lex();
432
320
  return false;
433
320
}
434
435
319
bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
436
319
  int64_t SymbolStorageClass;
437
319
  if (getParser().parseAbsoluteExpression(SymbolStorageClass))
438
0
    return true;
439
319
440
319
  if (getLexer().isNot(AsmToken::EndOfStatement))
441
0
    return TokError("unexpected token in directive");
442
319
443
319
  Lex();
444
319
  getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
445
319
  return false;
446
319
}
447
448
318
bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
449
318
  int64_t Type;
450
318
  if (getParser().parseAbsoluteExpression(Type))
451
0
    return true;
452
318
453
318
  if (getLexer().isNot(AsmToken::EndOfStatement))
454
0
    return TokError("unexpected token in directive");
455
318
456
318
  Lex();
457
318
  getStreamer().EmitCOFFSymbolType(Type);
458
318
  return false;
459
318
}
460
461
319
bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
462
319
  Lex();
463
319
  getStreamer().EndCOFFSymbolDef();
464
319
  return false;
465
319
}
466
467
178
bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
468
178
  StringRef SymbolID;
469
178
  if (getParser().parseIdentifier(SymbolID))
470
0
    return TokError("expected identifier in directive");
471
178
472
178
  int64_t Offset = 0;
473
178
  SMLoc OffsetLoc;
474
178
  if (getLexer().is(AsmToken::Plus)) {
475
0
    OffsetLoc = getLexer().getLoc();
476
0
    if (getParser().parseAbsoluteExpression(Offset))
477
0
      return true;
478
178
  }
479
178
480
178
  if (getLexer().isNot(AsmToken::EndOfStatement))
481
0
    return TokError("unexpected token in directive");
482
178
483
178
  if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max())
484
0
    return Error(
485
0
        OffsetLoc,
486
0
        "invalid '.secrel32' directive offset, can't be less "
487
0
        "than zero or greater than std::numeric_limits<uint32_t>::max()");
488
178
489
178
  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
490
178
491
178
  Lex();
492
178
  getStreamer().EmitCOFFSecRel32(Symbol, Offset);
493
178
  return false;
494
178
}
495
496
26
bool COFFAsmParser::ParseDirectiveRVA(StringRef, SMLoc) {
497
32
  auto parseOp = [&]() -> bool {
498
32
    StringRef SymbolID;
499
32
    if (getParser().parseIdentifier(SymbolID))
500
0
      return TokError("expected identifier in directive");
501
32
502
32
    int64_t Offset = 0;
503
32
    SMLoc OffsetLoc;
504
32
    if (getLexer().is(AsmToken::Plus) || 
getLexer().is(AsmToken::Minus)30
) {
505
4
      OffsetLoc = getLexer().getLoc();
506
4
      if (getParser().parseAbsoluteExpression(Offset))
507
0
        return true;
508
32
    }
509
32
510
32
    if (Offset < std::numeric_limits<int32_t>::min() ||
511
32
        Offset > std::numeric_limits<int32_t>::max())
512
0
      return Error(OffsetLoc, "invalid '.rva' directive offset, can't be less "
513
0
                              "than -2147483648 or greater than "
514
0
                              "2147483647");
515
32
516
32
    MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
517
32
518
32
    getStreamer().EmitCOFFImgRel32(Symbol, Offset);
519
32
    return false;
520
32
  };
521
26
522
26
  if (getParser().parseMany(parseOp))
523
0
    return addErrorSuffix(" in directive");
524
26
  return false;
525
26
}
526
527
5
bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
528
5
  StringRef SymbolID;
529
5
  if (getParser().parseIdentifier(SymbolID))
530
0
    return TokError("expected identifier in directive");
531
5
532
5
  if (getLexer().isNot(AsmToken::EndOfStatement))
533
0
    return TokError("unexpected token in directive");
534
5
535
5
  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
536
5
537
5
  Lex();
538
5
  getStreamer().EmitCOFFSafeSEH(Symbol);
539
5
  return false;
540
5
}
541
542
167
bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
543
167
  StringRef SymbolID;
544
167
  if (getParser().parseIdentifier(SymbolID))
545
0
    return TokError("expected identifier in directive");
546
167
547
167
  if (getLexer().isNot(AsmToken::EndOfStatement))
548
0
    return TokError("unexpected token in directive");
549
167
550
167
  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
551
167
552
167
  Lex();
553
167
  getStreamer().EmitCOFFSectionIndex(Symbol);
554
167
  return false;
555
167
}
556
557
10
bool COFFAsmParser::ParseDirectiveSymIdx(StringRef, SMLoc) {
558
10
  StringRef SymbolID;
559
10
  if (getParser().parseIdentifier(SymbolID))
560
0
    return TokError("expected identifier in directive");
561
10
562
10
  if (getLexer().isNot(AsmToken::EndOfStatement))
563
0
    return TokError("unexpected token in directive");
564
10
565
10
  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
566
10
567
10
  Lex();
568
10
  getStreamer().EmitCOFFSymbolIndex(Symbol);
569
10
  return false;
570
10
}
571
572
/// ::= [ identifier ]
573
306
bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
574
306
  StringRef TypeId = getTok().getIdentifier();
575
306
576
306
  Type = StringSwitch<COFF::COMDATType>(TypeId)
577
306
    .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
578
306
    .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
579
306
    .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
580
306
    .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
581
306
    .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
582
306
    .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
583
306
    .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
584
306
    .Default((COFF::COMDATType)0);
585
306
586
306
  if (Type == 0)
587
1
    return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
588
305
589
305
  Lex();
590
305
591
305
  return false;
592
305
}
593
594
/// ParseDirectiveLinkOnce
595
///  ::= .linkonce [ identifier ]
596
35
bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
597
35
  COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
598
35
  if (getLexer().is(AsmToken::Identifier))
599
33
    if (parseCOMDATType(Type))
600
1
      return true;
601
34
602
34
  const MCSectionCOFF *Current =
603
34
      static_cast<const MCSectionCOFF *>(getStreamer().getCurrentSectionOnly());
604
34
605
34
  if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
606
2
    return Error(Loc, "cannot make section associative with .linkonce");
607
32
608
32
  if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
609
1
    return Error(Loc, Twine("section '") + Current->getSectionName() +
610
1
                                                       "' is already linkonce");
611
31
612
31
  Current->setSelection(Type);
613
31
614
31
  if (getLexer().isNot(AsmToken::EndOfStatement))
615
1
    return TokError("unexpected token in directive");
616
30
617
30
  return false;
618
30
}
619
620
94
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
621
94
  StringRef SymbolID;
622
94
  if (getParser().parseIdentifier(SymbolID))
623
0
    return true;
624
94
625
94
  if (getLexer().isNot(AsmToken::EndOfStatement))
626
0
    return TokError("unexpected token in directive");
627
94
628
94
  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
629
94
630
94
  Lex();
631
94
  getStreamer().EmitWinCFIStartProc(Symbol, Loc);
632
94
  return false;
633
94
}
634
635
93
bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
636
93
  Lex();
637
93
  getStreamer().EmitWinCFIEndProc(Loc);
638
93
  return false;
639
93
}
640
641
3
bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
642
3
  Lex();
643
3
  getStreamer().EmitWinCFIStartChained(Loc);
644
3
  return false;
645
3
}
646
647
3
bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
648
3
  Lex();
649
3
  getStreamer().EmitWinCFIEndChained(Loc);
650
3
  return false;
651
3
}
652
653
5
bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
654
5
  StringRef SymbolID;
655
5
  if (getParser().parseIdentifier(SymbolID))
656
0
    return true;
657
5
658
5
  if (getLexer().isNot(AsmToken::Comma))
659
0
    return TokError("you must specify one or both of @unwind or @except");
660
5
  Lex();
661
5
  bool unwind = false, except = false;
662
5
  if (ParseAtUnwindOrAtExcept(unwind, except))
663
0
    return true;
664
5
  if (getLexer().is(AsmToken::Comma)) {
665
1
    Lex();
666
1
    if (ParseAtUnwindOrAtExcept(unwind, except))
667
0
      return true;
668
5
  }
669
5
  if (getLexer().isNot(AsmToken::EndOfStatement))
670
0
    return TokError("unexpected token in directive");
671
5
672
5
  MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
673
5
674
5
  Lex();
675
5
  getStreamer().EmitWinEHHandler(handler, unwind, except, Loc);
676
5
  return false;
677
5
}
678
679
83
bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
680
83
  Lex();
681
83
  getStreamer().EmitWinEHHandlerData();
682
83
  return false;
683
83
}
684
685
23
bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc Loc) {
686
23
  unsigned Reg = 0;
687
23
  if (ParseSEHRegisterNumber(Reg))
688
0
    return true;
689
23
690
23
  if (getLexer().isNot(AsmToken::EndOfStatement))
691
0
    return TokError("unexpected token in directive");
692
23
693
23
  Lex();
694
23
  getStreamer().EmitWinCFIPushReg(Reg, Loc);
695
23
  return false;
696
23
}
697
698
8
bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc Loc) {
699
8
  unsigned Reg = 0;
700
8
  int64_t Off;
701
8
  if (ParseSEHRegisterNumber(Reg))
702
0
    return true;
703
8
  if (getLexer().isNot(AsmToken::Comma))
704
1
    return TokError("you must specify a stack pointer offset");
705
7
706
7
  Lex();
707
7
  if (getParser().parseAbsoluteExpression(Off))
708
0
    return true;
709
7
710
7
  if (getLexer().isNot(AsmToken::EndOfStatement))
711
0
    return TokError("unexpected token in directive");
712
7
713
7
  Lex();
714
7
  getStreamer().EmitWinCFISetFrame(Reg, Off, Loc);
715
7
  return false;
716
7
}
717
718
88
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
719
88
  int64_t Size;
720
88
  if (getParser().parseAbsoluteExpression(Size))
721
0
    return true;
722
88
723
88
  if (getLexer().isNot(AsmToken::EndOfStatement))
724
0
    return TokError("unexpected token in directive");
725
88
726
88
  Lex();
727
88
  getStreamer().EmitWinCFIAllocStack(Size, Loc);
728
88
  return false;
729
88
}
730
731
2
bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc Loc) {
732
2
  unsigned Reg = 0;
733
2
  int64_t Off;
734
2
  if (ParseSEHRegisterNumber(Reg))
735
0
    return true;
736
2
  if (getLexer().isNot(AsmToken::Comma))
737
0
    return TokError("you must specify an offset on the stack");
738
2
739
2
  Lex();
740
2
  if (getParser().parseAbsoluteExpression(Off))
741
0
    return true;
742
2
743
2
  if (getLexer().isNot(AsmToken::EndOfStatement))
744
0
    return TokError("unexpected token in directive");
745
2
746
2
  Lex();
747
2
  // FIXME: Err on %xmm* registers
748
2
  getStreamer().EmitWinCFISaveReg(Reg, Off, Loc);
749
2
  return false;
750
2
}
751
752
// FIXME: This method is inherently x86-specific. It should really be in the
753
// x86 backend.
754
6
bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc Loc) {
755
6
  unsigned Reg = 0;
756
6
  int64_t Off;
757
6
  if (ParseSEHRegisterNumber(Reg))
758
0
    return true;
759
6
  if (getLexer().isNot(AsmToken::Comma))
760
1
    return TokError("you must specify an offset on the stack");
761
5
762
5
  Lex();
763
5
  if (getParser().parseAbsoluteExpression(Off))
764
0
    return true;
765
5
766
5
  if (getLexer().isNot(AsmToken::EndOfStatement))
767
0
    return TokError("unexpected token in directive");
768
5
769
5
  Lex();
770
5
  // FIXME: Err on non-%xmm* registers
771
5
  getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc);
772
5
  return false;
773
5
}
774
775
2
bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc Loc) {
776
2
  bool Code = false;
777
2
  StringRef CodeID;
778
2
  if (getLexer().is(AsmToken::At)) {
779
2
    SMLoc startLoc = getLexer().getLoc();
780
2
    Lex();
781
2
    if (!getParser().parseIdentifier(CodeID)) {
782
2
      if (CodeID != "code")
783
0
        return Error(startLoc, "expected @code");
784
2
      Code = true;
785
2
    }
786
2
  }
787
2
788
2
  if (getLexer().isNot(AsmToken::EndOfStatement))
789
0
    return TokError("unexpected token in directive");
790
2
791
2
  Lex();
792
2
  getStreamer().EmitWinCFIPushFrame(Code, Loc);
793
2
  return false;
794
2
}
795
796
92
bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
797
92
  Lex();
798
92
  getStreamer().EmitWinCFIEndProlog(Loc);
799
92
  return false;
800
92
}
801
802
6
bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
803
6
  StringRef identifier;
804
6
  if (getLexer().isNot(AsmToken::At))
805
0
    return TokError("a handler attribute must begin with '@'");
806
6
  SMLoc startLoc = getLexer().getLoc();
807
6
  Lex();
808
6
  if (getParser().parseIdentifier(identifier))
809
0
    return Error(startLoc, "expected @unwind or @except");
810
6
  if (identifier == "unwind")
811
1
    unwind = true;
812
5
  else if (identifier == "except")
813
5
    except = true;
814
0
  else
815
0
    return Error(startLoc, "expected @unwind or @except");
816
6
  return false;
817
6
}
818
819
39
bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
820
39
  SMLoc startLoc = getLexer().getLoc();
821
39
  if (getLexer().is(AsmToken::Percent)) {
822
7
    const MCRegisterInfo *MRI = getContext().getRegisterInfo();
823
7
    SMLoc endLoc;
824
7
    unsigned LLVMRegNo;
825
7
    if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
826
0
      return true;
827
7
828
#if 0
829
    // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
830
    // violation so this validation code is disabled.
831
832
    // Check that this is a non-volatile register.
833
    const unsigned *NVRegs = TAI.getCalleeSavedRegs();
834
    unsigned i;
835
    for (i = 0; NVRegs[i] != 0; ++i)
836
      if (NVRegs[i] == LLVMRegNo)
837
        break;
838
    if (NVRegs[i] == 0)
839
      return Error(startLoc, "expected non-volatile register");
840
#endif
841
842
7
    int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo);
843
7
    if (SEHRegNo < 0)
844
0
      return Error(startLoc,"register can't be represented in SEH unwind info");
845
7
    RegNo = SEHRegNo;
846
7
  }
847
32
  else {
848
32
    int64_t n;
849
32
    if (getParser().parseAbsoluteExpression(n))
850
0
      return true;
851
32
    if (n > 15)
852
0
      return Error(startLoc, "register number is too high");
853
32
    RegNo = n;
854
32
  }
855
39
856
39
  return false;
857
39
}
858
859
namespace llvm {
860
861
462
MCAsmParserExtension *createCOFFAsmParser() {
862
462
  return new COFFAsmParser;
863
462
}
864
865
} // end namespace llvm