aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp129
-rw-r--r--lib/MC/MCParser/AsmParser.cpp304
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp255
-rw-r--r--lib/MC/MCParser/MCAsmParserExtension.cpp3
4 files changed, 526 insertions, 165 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index 5c1ae2f..89374d0 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -15,7 +15,7 @@
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/MC/MCAsmInfo.h"
-#include <ctype.h>
+#include <cctype>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
@@ -31,12 +31,12 @@ AsmLexer::~AsmLexer() {
void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
CurBuf = buf;
-
+
if (ptr)
CurPtr = ptr;
else
CurPtr = CurBuf->getBufferStart();
-
+
TokStart = 0;
}
@@ -44,7 +44,7 @@ void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
/// location. This is defined to always return AsmToken::Error.
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
SetError(SMLoc::getFromPointer(Loc), Msg);
-
+
return AsmToken(AsmToken::Error, StringRef(Loc, 0));
}
@@ -58,9 +58,9 @@ int AsmLexer::getNextChar() {
// a random nul in the file. Disambiguate that here.
if (CurPtr-1 != CurBuf->getBufferEnd())
return 0; // Just whitespace.
-
+
// Otherwise, return end of file.
- --CurPtr; // Another call to lex will return EOF again.
+ --CurPtr; // Another call to lex will return EOF again.
return EOF;
}
}
@@ -106,11 +106,11 @@ AsmToken AsmLexer::LexIdentifier() {
while (IsIdentifierChar(*CurPtr))
++CurPtr;
-
+
// Handle . as a special case.
if (CurPtr == TokStart+1 && TokStart[0] == '.')
return AsmToken(AsmToken::Dot, StringRef(TokStart, 1));
-
+
return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
}
@@ -133,7 +133,7 @@ AsmToken AsmLexer::LexSlash() {
case '*':
// End of the comment?
if (CurPtr[0] != '/') break;
-
+
++CurPtr; // End the */.
return LexToken();
}
@@ -148,7 +148,7 @@ AsmToken AsmLexer::LexLineComment() {
int CurChar = getNextChar();
while (CurChar != '\n' && CurChar != '\n' && CurChar != EOF)
CurChar = getNextChar();
-
+
if (CurChar == EOF)
return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0));
return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0));
@@ -184,21 +184,21 @@ AsmToken AsmLexer::LexDigit() {
long long Value;
if (Result.getAsInteger(10, Value)) {
- // We have to handle minint_as_a_positive_value specially, because
- // - minint_as_a_positive_value = minint and it is valid.
- if (Result == "9223372036854775808")
- Value = -9223372036854775808ULL;
- else
- return ReturnError(TokStart, "Invalid decimal number");
+ // Allow positive values that are too large to fit into a signed 64-bit
+ // integer, but that do fit in an unsigned one, we just convert them over.
+ unsigned long long UValue;
+ if (Result.getAsInteger(10, UValue))
+ return ReturnError(TokStart, "invalid decimal number");
+ Value = (long long)UValue;
}
-
+
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
-
+
return AsmToken(AsmToken::Integer, Result, Value);
}
-
+
if (*CurPtr == 'b') {
++CurPtr;
// See if we actually have "0b" as part of something like "jmp 0b\n"
@@ -210,30 +210,30 @@ AsmToken AsmLexer::LexDigit() {
const char *NumStart = CurPtr;
while (CurPtr[0] == '0' || CurPtr[0] == '1')
++CurPtr;
-
+
// Requires at least one binary digit.
if (CurPtr == NumStart)
return ReturnError(TokStart, "Invalid binary number");
-
+
StringRef Result(TokStart, CurPtr - TokStart);
-
+
long long Value;
if (Result.substr(2).getAsInteger(2, Value))
return ReturnError(TokStart, "Invalid binary number");
-
+
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
-
+
return AsmToken(AsmToken::Integer, Result, Value);
}
-
+
if (*CurPtr == 'x') {
++CurPtr;
const char *NumStart = CurPtr;
while (isxdigit(CurPtr[0]))
++CurPtr;
-
+
// Requires at least one hex digit.
if (CurPtr == NumStart)
return ReturnError(CurPtr-2, "Invalid hexadecimal number");
@@ -241,31 +241,67 @@ AsmToken AsmLexer::LexDigit() {
unsigned long long Result;
if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
return ReturnError(TokStart, "Invalid hexadecimal number");
-
+
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
-
+
return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
(int64_t)Result);
}
-
+
// Must be an octal number, it starts with 0.
while (*CurPtr >= '0' && *CurPtr <= '7')
++CurPtr;
-
+
StringRef Result(TokStart, CurPtr - TokStart);
long long Value;
if (Result.getAsInteger(8, Value))
return ReturnError(TokStart, "Invalid octal number");
-
+
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
-
+
return AsmToken(AsmToken::Integer, Result, Value);
}
+/// LexSingleQuote: Integer: 'b'
+AsmToken AsmLexer::LexSingleQuote() {
+ int CurChar = getNextChar();
+
+ if (CurChar == '\\')
+ CurChar = getNextChar();
+
+ if (CurChar == EOF)
+ return ReturnError(TokStart, "unterminated single quote");
+
+ CurChar = getNextChar();
+
+ if (CurChar != '\'')
+ return ReturnError(TokStart, "single quote way too long");
+
+ // The idea here being that 'c' is basically just an integral
+ // constant.
+ StringRef Res = StringRef(TokStart,CurPtr - TokStart);
+ long long Value;
+
+ if (Res.startswith("\'\\")) {
+ char theChar = Res[2];
+ switch (theChar) {
+ default: Value = theChar; break;
+ case '\'': Value = '\''; break;
+ case 't': Value = '\t'; break;
+ case 'n': Value = '\n'; break;
+ case 'b': Value = '\b'; break;
+ }
+ } else
+ Value = TokStart[1];
+
+ return AsmToken(AsmToken::Integer, Res, Value);
+}
+
+
/// LexQuote: String: "..."
AsmToken AsmLexer::LexQuote() {
int CurChar = getNextChar();
@@ -275,13 +311,13 @@ AsmToken AsmLexer::LexQuote() {
// Allow \", etc.
CurChar = getNextChar();
}
-
+
if (CurChar == EOF)
return ReturnError(TokStart, "unterminated string constant");
CurChar = getNextChar();
}
-
+
return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
}
@@ -307,7 +343,7 @@ AsmToken AsmLexer::LexToken() {
TokStart = CurPtr;
// This always consumes at least one character.
int CurChar = getNextChar();
-
+
if (isAtStartOfComment(CurChar))
return LexLineComment();
@@ -316,7 +352,7 @@ AsmToken AsmLexer::LexToken() {
// Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
return LexIdentifier();
-
+
// Unknown character, emit an error.
return ReturnError(TokStart, "invalid character in input");
case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
@@ -342,49 +378,50 @@ AsmToken AsmLexer::LexToken() {
case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1));
- case '=':
+ case '=':
if (*CurPtr == '=')
return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
- case '|':
+ case '|':
if (*CurPtr == '|')
return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
- case '&':
+ case '&':
if (*CurPtr == '&')
return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
- case '!':
+ case '!':
if (*CurPtr == '=')
return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
case '/': return LexSlash();
case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
+ case '\'': return LexSingleQuote();
case '"': return LexQuote();
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return LexDigit();
case '<':
switch (*CurPtr) {
- case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
+ case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
+ case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
StringRef(TokStart, 2));
- case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
+ case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
StringRef(TokStart, 2));
default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
}
case '>':
switch (*CurPtr) {
- case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
+ case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
+ case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
StringRef(TokStart, 2));
default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
}
-
+
// TODO: Quoted identifiers (objc methods etc)
// local labels: [0-9][:]
// Forward/backward labels: [0-9][fb]
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index fa7a785..a84917f 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -30,6 +30,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetAsmParser.h"
#include <cctype>
#include <vector>
@@ -167,11 +168,12 @@ private:
/// will be either the EndOfStatement or EOF.
StringRef ParseStringToEndOfStatement();
- bool ParseAssignment(StringRef Name);
+ bool ParseAssignment(StringRef Name, bool allow_redef);
bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
+ bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \arg Res to the identifier contents.
@@ -186,7 +188,7 @@ private:
bool ParseDirectiveFill(); // ".fill"
bool ParseDirectiveSpace(); // ".space"
bool ParseDirectiveZero(); // ".zero"
- bool ParseDirectiveSet(StringRef IDVal); // ".set" or ".equ"
+ bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); // ".set", ".equ", ".equiv"
bool ParseDirectiveOrg(); // ".org"
// ".align{,32}", ".p2align{,w,l}"
bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
@@ -201,6 +203,8 @@ private:
bool ParseDirectiveInclude(); // ".include"
bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
+ // ".ifdef" or ".ifndef", depending on expect_defined
+ bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
@@ -221,7 +225,6 @@ class GenericAsmParser : public MCAsmParserExtension {
getParser().AddDirectiveHandler(this, Directive,
HandleDirective<GenericAsmParser, Handler>);
}
-
public:
GenericAsmParser() {}
@@ -239,6 +242,28 @@ public:
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLoc>(".loc");
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs");
+ // CFI directives.
+ AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>(
+ ".cfi_startproc");
+ AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>(
+ ".cfi_endproc");
+ AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>(
+ ".cfi_def_cfa");
+ AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>(
+ ".cfi_def_cfa_offset");
+ AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>(
+ ".cfi_def_cfa_register");
+ AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIOffset>(
+ ".cfi_offset");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
+
// Macro directives.
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
".macros_on");
@@ -252,10 +277,21 @@ public:
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128");
}
+ bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
+
bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
@@ -457,6 +493,20 @@ bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return false;
}
+/// ParseBracketExpr - Parse a bracket expression and return it.
+/// NOTE: This assumes the leading '[' has already been consumed.
+///
+/// bracketexpr ::= expr]
+///
+bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ if (ParseExpression(Res)) return true;
+ if (Lexer.isNot(AsmToken::RBrac))
+ return TokError("expected ']' in brackets expression");
+ EndLoc = Lexer.getLoc();
+ Lex();
+ return false;
+}
+
/// ParsePrimaryExpr - Parse a primary expression and return it.
/// primaryexpr ::= (parenexpr
/// primaryexpr ::= symbol
@@ -492,7 +542,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
if (Variant == MCSymbolRefExpr::VK_Invalid) {
Variant = MCSymbolRefExpr::VK_None;
- TokError("invalid variant '" + Split.second + "'");
+ return TokError("invalid variant '" + Split.second + "'");
}
}
@@ -532,6 +582,13 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
return false;
}
+ case AsmToken::Real: {
+ APFloat RealVal(APFloat::IEEEdouble, getTok().getString());
+ uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
+ Res = MCConstantExpr::Create(IntVal, getContext());
+ Lex(); // Eat token.
+ return false;
+ }
case AsmToken::Dot: {
// This is a '.' reference, which references the current PC. Emit a
// temporary label to the streamer and refer to it.
@@ -542,10 +599,14 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Lex(); // Eat identifier.
return false;
}
-
case AsmToken::LParen:
Lex(); // Eat the '('.
return ParseParenExpr(Res, EndLoc);
+ case AsmToken::LBrac:
+ if (!PlatformParser->HasBracketExpressions())
+ return TokError("brackets expression not supported on this target");
+ Lex(); // Eat the '['.
+ return ParseBracketExpr(Res, EndLoc);
case AsmToken::Minus:
Lex(); // Eat the operator.
if (ParsePrimaryExpr(Res, EndLoc))
@@ -809,12 +870,17 @@ bool AsmParser::ParseStatement() {
return false;
}
- // Statements always start with an identifier.
+ // Statements always start with an identifier or are a full line comment.
AsmToken ID = getTok();
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
int64_t LocalLabelVal = -1;
- // GUESS allow an integer followed by a ':' as a directional local label
+ // A full line comment is a '#' as the first token.
+ if (Lexer.is(AsmToken::Hash)) {
+ EatToEndOfStatement();
+ return false;
+ }
+ // Allow an integer followed by a ':' as a directional local label.
if (Lexer.is(AsmToken::Integer)) {
LocalLabelVal = getTok().getIntVal();
if (LocalLabelVal < 0) {
@@ -842,6 +908,10 @@ bool AsmParser::ParseStatement() {
// example.
if (IDVal == ".if")
return ParseDirectiveIf(IDLoc);
+ if (IDVal == ".ifdef")
+ return ParseDirectiveIfdef(IDLoc, true);
+ if (IDVal == ".ifndef" || IDVal == ".ifnotdef")
+ return ParseDirectiveIfdef(IDLoc, false);
if (IDVal == ".elseif")
return ParseDirectiveElseIf(IDLoc);
if (IDVal == ".else")
@@ -896,7 +966,7 @@ bool AsmParser::ParseStatement() {
// identifier '=' ... -> assignment statement
Lex();
- return ParseAssignment(IDVal);
+ return ParseAssignment(IDVal, true);
default: // Normal instruction or directive.
break;
@@ -911,7 +981,9 @@ bool AsmParser::ParseStatement() {
if (IDVal[0] == '.') {
// Assembler features
if (IDVal == ".set" || IDVal == ".equ")
- return ParseDirectiveSet(IDVal);
+ return ParseDirectiveSet(IDVal, true);
+ if (IDVal == ".equiv")
+ return ParseDirectiveSet(IDVal, false);
// Data directives
@@ -926,11 +998,19 @@ bool AsmParser::ParseStatement() {
return ParseDirectiveValue(2);
if (IDVal == ".value")
return ParseDirectiveValue(2);
+ if (IDVal == ".2byte")
+ return ParseDirectiveValue(2);
if (IDVal == ".long")
return ParseDirectiveValue(4);
+ if (IDVal == ".int")
+ return ParseDirectiveValue(4);
+ if (IDVal == ".4byte")
+ return ParseDirectiveValue(4);
if (IDVal == ".quad")
return ParseDirectiveValue(8);
- if (IDVal == ".single")
+ if (IDVal == ".8byte")
+ return ParseDirectiveValue(8);
+ if (IDVal == ".single" || IDVal == ".float")
return ParseDirectiveRealValue(APFloat::IEEEsingle);
if (IDVal == ".double")
return ParseDirectiveRealValue(APFloat::IEEEdouble);
@@ -983,6 +1063,8 @@ bool AsmParser::ParseStatement() {
return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
if (IDVal == ".no_dead_strip")
return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
+ if (IDVal == ".symbol_resolver")
+ return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver);
if (IDVal == ".private_extern")
return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
if (IDVal == ".protected")
@@ -1008,6 +1090,9 @@ bool AsmParser::ParseStatement() {
if (IDVal == ".include")
return ParseDirectiveInclude();
+ if (IDVal == ".code16" || IDVal == ".code32" || IDVal == ".code64")
+ return TokError(Twine(IDVal) + " not supported yet");
+
// Look up the handler in the handler table.
std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
DirectiveMap.lookup(IDVal);
@@ -1208,7 +1293,7 @@ static void MarkUsed(const MCExpr *Value) {
}
}
-bool AsmParser::ParseAssignment(StringRef Name) {
+bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
// FIXME: Use better location, we should use proper tokens.
SMLoc EqualLoc = Lexer.getLoc();
@@ -1234,7 +1319,7 @@ bool AsmParser::ParseAssignment(StringRef Name) {
// FIXME: Diagnose assignment to protected identifier (e.g., register name).
if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
; // Allow redefinitions of undefined symbols only used in directives.
- else if (!Sym->isUndefined() && !Sym->isAbsolute())
+ else if (!Sym->isUndefined() && (!Sym->isAbsolute() || !allow_redef))
return Error(EqualLoc, "redefinition of '" + Name + "'");
else if (!Sym->isVariable())
return Error(EqualLoc, "invalid assignment to '" + Name + "'");
@@ -1295,8 +1380,10 @@ bool AsmParser::ParseIdentifier(StringRef &Res) {
}
/// ParseDirectiveSet:
+/// ::= .equ identifier ',' expression
+/// ::= .equiv identifier ',' expression
/// ::= .set identifier ',' expression
-bool AsmParser::ParseDirectiveSet(StringRef IDVal) {
+bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
if (ParseIdentifier(Name))
@@ -1306,7 +1393,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal) {
return TokError("unexpected token in '" + Twine(IDVal) + "'");
Lex();
- return ParseAssignment(Name);
+ return ParseAssignment(Name, allow_redef);
}
bool AsmParser::ParseEscapedString(std::string &Data) {
@@ -1871,6 +1958,31 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
return false;
}
+bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
+ StringRef Name;
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+
+ if (TheCondState.Ignore) {
+ EatToEndOfStatement();
+ } else {
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier after '.ifdef'");
+
+ Lex();
+
+ MCSymbol *Sym = getContext().LookupSymbol(Name);
+
+ if (expect_defined)
+ TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined());
+ else
+ TheCondState.CondMet = (Sym == NULL || Sym->isUndefined());
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
/// ParseDirectiveElseIf
/// ::= .elseif expression
bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
@@ -1974,9 +2086,8 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
if (FileNumber == -1)
getStreamer().EmitFileDirective(Filename);
else {
- if (getContext().GetDwarfFile(Filename, FileNumber) == 0)
+ if (getStreamer().EmitDwarfFileDirective(FileNumber, Filename))
Error(FileNumberLoc, "file number already allocated");
- getStreamer().EmitDwarfFileDirective(FileNumber, Filename);
}
return false;
@@ -2104,8 +2215,8 @@ bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
}
}
- getContext().setCurrentDwarfLoc(FileNumber, LineNumber, ColumnPos, Flags,
- Isa, Discriminator);
+ getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
+ Isa, Discriminator);
return false;
}
@@ -2117,6 +2228,163 @@ bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive,
return TokError("unsupported directive '" + Directive + "'");
}
+/// ParseDirectiveCFIStartProc
+/// ::= .cfi_startproc
+bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef,
+ SMLoc DirectiveLoc) {
+ return getStreamer().EmitCFIStartProc();
+}
+
+/// ParseDirectiveCFIEndProc
+/// ::= .cfi_endproc
+bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) {
+ return getStreamer().EmitCFIEndProc();
+}
+
+/// ParseRegisterOrRegisterNumber - parse register name or number.
+bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register,
+ SMLoc DirectiveLoc) {
+ unsigned RegNo;
+
+ if (getLexer().is(AsmToken::Percent)) {
+ if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc,
+ DirectiveLoc))
+ return true;
+ Register = getContext().getTargetAsmInfo().getDwarfRegNum(RegNo, true);
+ } else
+ return getParser().ParseAbsoluteExpression(Register);
+
+ return false;
+}
+
+/// ParseDirectiveCFIDefCfa
+/// ::= .cfi_def_cfa register, offset
+bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
+ SMLoc DirectiveLoc) {
+ int64_t Register = 0;
+ if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Offset = 0;
+ if (getParser().ParseAbsoluteExpression(Offset))
+ return true;
+
+ return getStreamer().EmitCFIDefCfa(Register, Offset);
+}
+
+/// ParseDirectiveCFIDefCfaOffset
+/// ::= .cfi_def_cfa_offset offset
+bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef,
+ SMLoc DirectiveLoc) {
+ int64_t Offset = 0;
+ if (getParser().ParseAbsoluteExpression(Offset))
+ return true;
+
+ return getStreamer().EmitCFIDefCfaOffset(Offset);
+}
+
+/// ParseDirectiveCFIDefCfaRegister
+/// ::= .cfi_def_cfa_register register
+bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef,
+ SMLoc DirectiveLoc) {
+ int64_t Register = 0;
+ if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ return true;
+
+ return getStreamer().EmitCFIDefCfaRegister(Register);
+}
+
+/// ParseDirectiveCFIOffset
+/// ::= .cfi_off register, offset
+bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) {
+ int64_t Register = 0;
+ int64_t Offset = 0;
+
+ if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ if (getParser().ParseAbsoluteExpression(Offset))
+ return true;
+
+ return getStreamer().EmitCFIOffset(Register, Offset);
+}
+
+static bool isValidEncoding(int64_t Encoding) {
+ if (Encoding & ~0xff)
+ return false;
+
+ if (Encoding == dwarf::DW_EH_PE_omit)
+ return true;
+
+ const unsigned Format = Encoding & 0xf;
+ if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
+ Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
+ Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
+ Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
+ return false;
+
+ const unsigned Application = Encoding & 0x70;
+ if (Application != dwarf::DW_EH_PE_absptr &&
+ Application != dwarf::DW_EH_PE_pcrel)
+ return false;
+
+ return true;
+}
+
+/// ParseDirectiveCFIPersonalityOrLsda
+/// ::= .cfi_personality encoding, [symbol_name]
+/// ::= .cfi_lsda encoding, [symbol_name]
+bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ int64_t Encoding = 0;
+ if (getParser().ParseAbsoluteExpression(Encoding))
+ return true;
+ if (Encoding == dwarf::DW_EH_PE_omit)
+ return false;
+
+ if (!isValidEncoding(Encoding))
+ return TokError("unsupported encoding.");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ StringRef Name;
+ if (getParser().ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+
+ if (IDVal == ".cfi_personality")
+ return getStreamer().EmitCFIPersonality(Sym, Encoding);
+ else {
+ assert(IDVal == ".cfi_lsda");
+ return getStreamer().EmitCFILsda(Sym, Encoding);
+ }
+}
+
+/// ParseDirectiveCFIRememberState
+/// ::= .cfi_remember_state
+bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ return getStreamer().EmitCFIRememberState();
+}
+
+/// ParseDirectiveCFIRestoreState
+/// ::= .cfi_remember_state
+bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ return getStreamer().EmitCFIRestoreState();
+}
+
/// ParseDirectiveMacrosOnOff
/// ::= .macros_on
/// ::= .macros_off
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index d074ea9..dcf689a 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/ELF.h"
using namespace llvm;
namespace {
@@ -29,9 +30,12 @@ class ELFAsmParser : public MCAsmParserExtension {
bool ParseSectionSwitch(StringRef Section, unsigned Type,
unsigned Flags, SectionKind Kind);
+ bool SeenIdent;
public:
- ELFAsmParser() {}
+ ELFAsmParser() : SeenIdent(false) {
+ BracketExpressionsSupported = true;
+ }
virtual void Initialize(MCAsmParser &Parser) {
// Call the base implementation.
@@ -48,6 +52,8 @@ public:
AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local");
AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
+ AddDirectiveHandler<&ELFAsmParser::ParseDirectivePushSection>(".pushsection");
+ AddDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
@@ -59,61 +65,63 @@ public:
// FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
// the best way for us to get access to it?
bool ParseSectionDirectiveData(StringRef, SMLoc) {
- return ParseSectionSwitch(".data", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
+ return ParseSectionSwitch(".data", ELF::SHT_PROGBITS,
+ ELF::SHF_WRITE |ELF::SHF_ALLOC,
SectionKind::getDataRel());
}
bool ParseSectionDirectiveText(StringRef, SMLoc) {
- return ParseSectionSwitch(".text", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_EXECINSTR |
- MCSectionELF::SHF_ALLOC, SectionKind::getText());
+ return ParseSectionSwitch(".text", ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR |
+ ELF::SHF_ALLOC, SectionKind::getText());
}
bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
- return ParseSectionSwitch(".bss", MCSectionELF::SHT_NOBITS,
- MCSectionELF::SHF_WRITE |
- MCSectionELF::SHF_ALLOC, SectionKind::getBSS());
+ return ParseSectionSwitch(".bss", ELF::SHT_NOBITS,
+ ELF::SHF_WRITE |
+ ELF::SHF_ALLOC, SectionKind::getBSS());
}
bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
- return ParseSectionSwitch(".rodata", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC,
+ return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC,
SectionKind::getReadOnly());
}
bool ParseSectionDirectiveTData(StringRef, SMLoc) {
- return ParseSectionSwitch(".tdata", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_TLS | MCSectionELF::SHF_WRITE,
+ return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC |
+ ELF::SHF_TLS | ELF::SHF_WRITE,
SectionKind::getThreadData());
}
bool ParseSectionDirectiveTBSS(StringRef, SMLoc) {
- return ParseSectionSwitch(".tbss", MCSectionELF::SHT_NOBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_TLS | MCSectionELF::SHF_WRITE,
+ return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS,
+ ELF::SHF_ALLOC |
+ ELF::SHF_TLS | ELF::SHF_WRITE,
SectionKind::getThreadBSS());
}
bool ParseSectionDirectiveDataRel(StringRef, SMLoc) {
- return ParseSectionSwitch(".data.rel", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_WRITE,
+ return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC |
+ ELF::SHF_WRITE,
SectionKind::getDataRel());
}
bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) {
- return ParseSectionSwitch(".data.rel.ro", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_WRITE,
+ return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC |
+ ELF::SHF_WRITE,
SectionKind::getReadOnlyWithRel());
}
bool ParseSectionDirectiveDataRelRoLocal(StringRef, SMLoc) {
- return ParseSectionSwitch(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_WRITE,
+ return ParseSectionSwitch(".data.rel.ro.local", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC |
+ ELF::SHF_WRITE,
SectionKind::getReadOnlyWithRelLocal());
}
bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
- return ParseSectionSwitch(".eh_frame", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_WRITE,
+ return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC |
+ ELF::SHF_WRITE,
SectionKind::getDataRel());
}
+ bool ParseDirectivePushSection(StringRef, SMLoc);
+ bool ParseDirectivePopSection(StringRef, SMLoc);
bool ParseDirectiveSection(StringRef, SMLoc);
bool ParseDirectiveSize(StringRef, SMLoc);
bool ParseDirectivePrevious(StringRef, SMLoc);
@@ -167,6 +175,12 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
SMLoc FirstLoc = getLexer().getLoc();
unsigned Size = 0;
+ if (getLexer().is(AsmToken::String)) {
+ SectionName = getTok().getIdentifier();
+ Lex();
+ return false;
+ }
+
for (;;) {
StringRef Tmp;
unsigned CurSize;
@@ -175,10 +189,15 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
if (getLexer().is(AsmToken::Minus)) {
CurSize = 1;
Lex(); // Consume the "-".
- } else if (!getParser().ParseIdentifier(Tmp))
- CurSize = Tmp.size();
- else
+ } else if (getLexer().is(AsmToken::String)) {
+ CurSize = getTok().getIdentifier().size() + 2;
+ Lex();
+ } else if (getLexer().is(AsmToken::Identifier)) {
+ CurSize = getTok().getIdentifier().size();
+ Lex();
+ } else {
break;
+ }
Size += CurSize;
SectionName = StringRef(FirstLoc.getPointer(), Size);
@@ -193,6 +212,71 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
return false;
}
+static SectionKind computeSectionKind(unsigned Flags) {
+ if (Flags & ELF::SHF_EXECINSTR)
+ return SectionKind::getText();
+ if (Flags & ELF::SHF_TLS)
+ return SectionKind::getThreadData();
+ return SectionKind::getDataRel();
+}
+
+static int parseSectionFlags(StringRef flagsStr) {
+ int flags = 0;
+
+ for (unsigned i = 0; i < flagsStr.size(); i++) {
+ switch (flagsStr[i]) {
+ case 'a':
+ flags |= ELF::SHF_ALLOC;
+ break;
+ case 'x':
+ flags |= ELF::SHF_EXECINSTR;
+ break;
+ case 'w':
+ flags |= ELF::SHF_WRITE;
+ break;
+ case 'M':
+ flags |= ELF::SHF_MERGE;
+ break;
+ case 'S':
+ flags |= ELF::SHF_STRINGS;
+ break;
+ case 'T':
+ flags |= ELF::SHF_TLS;
+ break;
+ case 'c':
+ flags |= ELF::XCORE_SHF_CP_SECTION;
+ break;
+ case 'd':
+ flags |= ELF::XCORE_SHF_DP_SECTION;
+ break;
+ case 'G':
+ flags |= ELF::SHF_GROUP;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ return flags;
+}
+
+bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
+ getStreamer().PushSection();
+
+ if (ParseDirectiveSection(s, loc)) {
+ getStreamer().PopSection();
+ return true;
+ }
+
+ return false;
+}
+
+bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
+ if (!getStreamer().PopSection())
+ return TokError(".popsection without corresponding .pushsection");
+ return false;
+}
+
// FIXME: This is a work in progress.
bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
StringRef SectionName;
@@ -200,21 +284,34 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
if (ParseSectionName(SectionName))
return TokError("expected identifier in directive");
- StringRef FlagsStr;
StringRef TypeName;
int64_t Size = 0;
StringRef GroupName;
+ unsigned Flags = 0;
+
+ // Set the defaults first.
+ if (SectionName == ".fini" || SectionName == ".init" ||
+ SectionName == ".rodata")
+ Flags |= ELF::SHF_ALLOC;
+ if (SectionName == ".fini" || SectionName == ".init")
+ Flags |= ELF::SHF_EXECINSTR;
+
if (getLexer().is(AsmToken::Comma)) {
Lex();
if (getLexer().isNot(AsmToken::String))
return TokError("expected string in directive");
- FlagsStr = getTok().getStringContents();
+ StringRef FlagsStr = getTok().getStringContents();
Lex();
- bool Mergeable = FlagsStr.find('M') != StringRef::npos;
- bool Group = FlagsStr.find('G') != StringRef::npos;
+ int extraFlags = parseSectionFlags(FlagsStr);
+ if (extraFlags < 0)
+ return TokError("unknown flag");
+ Flags |= extraFlags;
+
+ bool Mergeable = Flags & ELF::SHF_MERGE;
+ bool Group = Flags & ELF::SHF_GROUP;
if (getLexer().isNot(AsmToken::Comma)) {
if (Mergeable)
@@ -261,70 +358,28 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
- unsigned Flags = 0;
- unsigned Type = MCSectionELF::SHT_NULL;
-
- // Set the defaults first.
- if (SectionName == ".fini" || SectionName == ".init" || SectionName == ".rodata") {
- Type = MCSectionELF::SHT_PROGBITS;
- Flags |= MCSectionELF::SHF_ALLOC;
- }
- if (SectionName == ".fini" || SectionName == ".init") {
- Flags |= MCSectionELF::SHF_EXECINSTR;
- }
-
- for (unsigned i = 0; i < FlagsStr.size(); i++) {
- switch (FlagsStr[i]) {
- case 'a':
- Flags |= MCSectionELF::SHF_ALLOC;
- break;
- case 'x':
- Flags |= MCSectionELF::SHF_EXECINSTR;
- break;
- case 'w':
- Flags |= MCSectionELF::SHF_WRITE;
- break;
- case 'M':
- Flags |= MCSectionELF::SHF_MERGE;
- break;
- case 'S':
- Flags |= MCSectionELF::SHF_STRINGS;
- break;
- case 'T':
- Flags |= MCSectionELF::SHF_TLS;
- break;
- case 'c':
- Flags |= MCSectionELF::XCORE_SHF_CP_SECTION;
- break;
- case 'd':
- Flags |= MCSectionELF::XCORE_SHF_DP_SECTION;
- break;
- case 'G':
- Flags |= MCSectionELF::SHF_GROUP;
- break;
- default:
- return TokError("unknown flag");
- }
- }
+ unsigned Type = ELF::SHT_PROGBITS;
if (!TypeName.empty()) {
if (TypeName == "init_array")
- Type = MCSectionELF::SHT_INIT_ARRAY;
+ Type = ELF::SHT_INIT_ARRAY;
else if (TypeName == "fini_array")
- Type = MCSectionELF::SHT_FINI_ARRAY;
+ Type = ELF::SHT_FINI_ARRAY;
else if (TypeName == "preinit_array")
- Type = MCSectionELF::SHT_PREINIT_ARRAY;
+ Type = ELF::SHT_PREINIT_ARRAY;
else if (TypeName == "nobits")
- Type = MCSectionELF::SHT_NOBITS;
+ Type = ELF::SHT_NOBITS;
else if (TypeName == "progbits")
- Type = MCSectionELF::SHT_PROGBITS;
+ Type = ELF::SHT_PROGBITS;
+ else if (TypeName == "note")
+ Type = ELF::SHT_NOTE;
+ else if (TypeName == "unwind")
+ Type = ELF::SHT_X86_64_UNWIND;
else
return TokError("unknown section type");
}
- SectionKind Kind = (Flags & MCSectionELF::SHF_EXECINSTR)
- ? SectionKind::getText()
- : SectionKind::getDataRel();
+ SectionKind Kind = computeSectionKind(Flags);
getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
Flags, Kind, Size,
GroupName));
@@ -333,8 +388,9 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
const MCSection *PreviousSection = getStreamer().getPreviousSection();
- if (PreviousSection != NULL)
- getStreamer().SwitchSection(PreviousSection);
+ if (PreviousSection == NULL)
+ return TokError(".previous without corresponding .section");
+ getStreamer().SwitchSection(PreviousSection);
return false;
}
@@ -396,23 +452,22 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
Lex();
- const MCSection *OldSection = getStreamer().getCurrentSection();
const MCSection *Comment =
- getContext().getELFSection(".comment", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_MERGE |
- MCSectionELF::SHF_STRINGS,
+ getContext().getELFSection(".comment", ELF::SHT_PROGBITS,
+ ELF::SHF_MERGE |
+ ELF::SHF_STRINGS,
SectionKind::getReadOnly(),
1, "");
- static bool First = true;
-
+ getStreamer().PushSection();
getStreamer().SwitchSection(Comment);
- if (First)
+ if (!SeenIdent) {
getStreamer().EmitIntValue(0, 1);
- First = false;
+ SeenIdent = true;
+ }
getStreamer().EmitBytes(Data, 0);
getStreamer().EmitIntValue(0, 1);
- getStreamer().SwitchSection(OldSection);
+ getStreamer().PopSection();
return false;
}
diff --git a/lib/MC/MCParser/MCAsmParserExtension.cpp b/lib/MC/MCParser/MCAsmParserExtension.cpp
index c30d306..3f25a14 100644
--- a/lib/MC/MCParser/MCAsmParserExtension.cpp
+++ b/lib/MC/MCParser/MCAsmParserExtension.cpp
@@ -10,7 +10,8 @@
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
using namespace llvm;
-MCAsmParserExtension::MCAsmParserExtension() {
+MCAsmParserExtension::MCAsmParserExtension() :
+ BracketExpressionsSupported(false) {
}
MCAsmParserExtension::~MCAsmParserExtension() {