/// primaryexpr ::= number
/// primaryexpr ::= '.'
/// primaryexpr ::= ~,+,-,'not' primaryexpr
+/// primaryexpr ::= string
+/// (a string is interpreted as a 64-bit number in big-endian base-256)
bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
AsmTypeInfo *TypeInfo) {
SMLoc FirstTokenLoc = getLexer().getLoc();
return false;
case AsmToken::Dollar:
case AsmToken::At:
- case AsmToken::String:
case AsmToken::Identifier: {
StringRef Identifier;
if (parseIdentifier(Identifier)) {
}
return false;
}
+ case AsmToken::String: {
+ // MASM strings (used as constants) are interpreted as big-endian base-256.
+ SMLoc ValueLoc = getTok().getLoc();
+ std::string Value;
+ if (parseEscapedString(Value))
+ return true;
+ if (Value.size() > 8)
+ return Error(ValueLoc, "literal value out of range");
+ uint64_t IntValue = 0;
+ for (const unsigned char CharVal : Value)
+ IntValue = (IntValue << 8) | CharVal;
+ Res = MCConstantExpr::create(IntValue, getContext());
+ return false;
+ }
case AsmToken::Real: {
APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
bool MasmParser::parseScalarInitializer(unsigned Size,
SmallVectorImpl<const MCExpr *> &Values,
unsigned StringPadLength) {
- if (getTok().is(AsmToken::String)) {
+ if (Size == 1 && getTok().is(AsmToken::String)) {
std::string Value;
if (parseEscapedString(Value))
return true;
- if (Size == 1) {
- // Treat each character as an initializer.
- for (const char CharVal : Value)
- Values.push_back(MCConstantExpr::create(CharVal, getContext()));
-
- // Pad the string with spaces to the specified length.
- for (size_t i = Value.size(); i < StringPadLength; ++i)
- Values.push_back(MCConstantExpr::create(' ', getContext()));
- } else {
- // Treat the string as an initial value in big-endian representation.
- if (Value.size() > Size)
- return Error(getTok().getLoc(), "out of range literal value");
-
- uint64_t IntValue = 0;
- for (const unsigned char CharVal : Value)
- IntValue = (IntValue << 8) | CharVal;
- Values.push_back(MCConstantExpr::create(IntValue, getContext()));
- }
+ // Treat each character as an initializer.
+ for (const unsigned char CharVal : Value)
+ Values.push_back(MCConstantExpr::create(CharVal, getContext()));
+
+ // Pad the string with spaces to the specified length.
+ for (size_t i = Value.size(); i < StringPadLength; ++i)
+ Values.push_back(MCConstantExpr::create(' ', getContext()));
} else {
const MCExpr *Value;
if (parseExpression(Value))
return Error(Tok.getLoc(), "unknown token in expression");
}
LLVM_FALLTHROUGH;
+ case AsmToken::String: {
+ if (Parser.isParsingMasm()) {
+ // MASM parsers handle strings in expressions as constants.
+ SMLoc ValueLoc = Tok.getLoc();
+ int64_t Res;
+ const MCExpr *Val;
+ if (Parser.parsePrimaryExpr(Val, End, nullptr))
+ return true;
+ UpdateLocLex = false;
+ if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
+ return Error(ValueLoc, "expected absolute value");
+ if (SM.onInteger(Res, ErrMsg))
+ return Error(ValueLoc, ErrMsg);
+ break;
+ }
+ LLVM_FALLTHROUGH;
+ }
case AsmToken::At:
- case AsmToken::String:
case AsmToken::Identifier: {
- if (Parser.isParsingMasm() && Tok.is(AsmToken::String)) {
- // Single-character strings should be treated as integer constants. This
- // includes MASM escapes for quotes.
- char Quote = Tok.getString().front();
- StringRef Contents = Tok.getStringContents();
- if (Contents.size() == 1 || Contents == std::string(2, Quote)) {
- if (SM.onInteger(Contents.front(), ErrMsg))
- return Error(Tok.getLoc(), ErrMsg);
- break;
- }
- }
SMLoc IdentLoc = Tok.getLoc();
StringRef Identifier = Tok.getString();
UpdateLocLex = false;