18
18
#include " llvm/ADT/APInt.h"
19
19
#include " llvm/ADT/ArrayRef.h"
20
20
#include " llvm/ADT/STLExtras.h"
21
+ #include " llvm/ADT/ScopeExit.h"
21
22
#include " llvm/ADT/SmallSet.h"
22
23
#include " llvm/ADT/SmallVector.h"
23
24
#include " llvm/ADT/StringExtras.h"
24
25
#include " llvm/ADT/StringMap.h"
25
26
#include " llvm/ADT/StringRef.h"
26
27
#include " llvm/ADT/StringSwitch.h"
27
28
#include " llvm/ADT/Twine.h"
29
+ #include " llvm/MC/MCAsmInfo.h"
28
30
#include " llvm/MC/MCContext.h"
29
31
#include " llvm/MC/MCExpr.h"
30
32
#include " llvm/MC/MCInst.h"
@@ -180,6 +182,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
180
182
bool showMatchError (SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
181
183
OperandVector &Operands);
182
184
185
+ bool parseDataExpr (const MCExpr *&Res) override ;
183
186
bool parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc);
184
187
185
188
bool parseDirectiveArch (SMLoc L);
@@ -335,8 +338,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
335
338
unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
336
339
unsigned Kind) override ;
337
340
338
- bool parsePrimaryExpr (const MCExpr *&Res, SMLoc &EndLoc) override ;
339
-
340
341
static bool classifySymbolRef (const MCExpr *Expr,
341
342
AArch64MCExpr::Specifier &ELFSpec,
342
343
MCSymbolRefExpr::VariantKind &DarwinRefKind,
@@ -4478,6 +4479,18 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
4478
4479
if (HasELFModifier)
4479
4480
ImmVal = AArch64MCExpr::create (ImmVal, RefKind, getContext ());
4480
4481
4482
+ if (getContext ().getAsmInfo ()->hasSubsectionsViaSymbols () &&
4483
+ parseOptionalToken (AsmToken::At)) {
4484
+ StringRef Spec;
4485
+ if (getParser ().parseIdentifier (Spec))
4486
+ return Error (getLoc (), " expected specifier after '@'" );
4487
+ if (auto *SRE = dyn_cast<MCSymbolRefExpr>(ImmVal)) {
4488
+ auto MaybeSpec = getContext ().getAsmInfo ()->getSpecifierForName (Spec);
4489
+ ImmVal =
4490
+ MCSymbolRefExpr::create (&SRE->getSymbol (), *MaybeSpec, getContext ());
4491
+ }
4492
+ }
4493
+
4481
4494
return false ;
4482
4495
}
4483
4496
@@ -8086,11 +8099,48 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8086
8099
return false ;
8087
8100
}
8088
8101
8089
- bool AArch64AsmParser::parsePrimaryExpr (const MCExpr *&Res, SMLoc &EndLoc) {
8090
- // Try @AUTH expressions: they're more complex than the usual symbol variants.
8091
- if (!parseAuthExpr (Res, EndLoc))
8102
+ bool AArch64AsmParser::parseDataExpr (const MCExpr *&Res) {
8103
+ SMLoc EndLoc;
8104
+
8105
+ if (getParser ().parseExpression (Res))
8106
+ return true ;
8107
+ MCAsmParser &Parser = getParser ();
8108
+ if (!parseOptionalToken (AsmToken::At))
8092
8109
return false ;
8093
- return getParser ().parsePrimaryExpr (Res, EndLoc, nullptr );
8110
+ if (getLexer ().getKind () != AsmToken::Identifier)
8111
+ return Error (getLoc (), " expected relocation specifier" );
8112
+
8113
+ std::string Identifier = Parser.getTok ().getIdentifier ().lower ();
8114
+ SMLoc Loc = getLoc ();
8115
+ Lex ();
8116
+ if (Identifier == " auth" )
8117
+ return parseAuthExpr (Res, EndLoc);
8118
+
8119
+ auto Spec = MCSymbolRefExpr::VK_PLT;
8120
+ if (Identifier == " gotpcrel" )
8121
+ Spec = MCSymbolRefExpr::VK_GOTPCREL;
8122
+ else if (Identifier != " plt" )
8123
+ return Error (Loc, " invalid relocation specifier" );
8124
+ if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Res))
8125
+ Res = MCSymbolRefExpr::create (&SRE->getSymbol (), Spec, getContext (),
8126
+ SRE->getLoc ());
8127
+ else
8128
+ return Error (Loc, " this relocation specifier must follow a symbol" );
8129
+
8130
+ for (;;) {
8131
+ std::optional<MCBinaryExpr::Opcode> Opcode;
8132
+ if (parseOptionalToken (AsmToken::Plus))
8133
+ Opcode = MCBinaryExpr::Add;
8134
+ else if (parseOptionalToken (AsmToken::Minus))
8135
+ Opcode = MCBinaryExpr::Sub;
8136
+ else
8137
+ break ;
8138
+ const MCExpr *Term;
8139
+ if (getParser ().parsePrimaryExpr (Term, EndLoc, nullptr ))
8140
+ return true ;
8141
+ Res = MCBinaryExpr::create (*Opcode, Res, Term, getContext ());
8142
+ }
8143
+ return false ;
8094
8144
}
8095
8145
8096
8146
// / parseAuthExpr
@@ -8100,54 +8150,8 @@ bool AArch64AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
8100
8150
bool AArch64AsmParser::parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc) {
8101
8151
MCAsmParser &Parser = getParser ();
8102
8152
MCContext &Ctx = getContext ();
8103
-
8104
8153
AsmToken Tok = Parser.getTok ();
8105
8154
8106
- // Look for '_sym@AUTH' ...
8107
- if (Tok.is (AsmToken::Identifier) && Tok.getIdentifier ().ends_with (" @AUTH" )) {
8108
- StringRef SymName = Tok.getIdentifier ().drop_back (strlen (" @AUTH" ));
8109
- if (SymName.contains (' @' ))
8110
- return TokError (
8111
- " combination of @AUTH with other modifiers not supported" );
8112
- Res = MCSymbolRefExpr::create (Ctx.getOrCreateSymbol (SymName), Ctx);
8113
-
8114
- Parser.Lex (); // Eat the identifier.
8115
- } else {
8116
- // ... or look for a more complex symbol reference, such as ...
8117
- SmallVector<AsmToken, 6 > Tokens;
8118
-
8119
- // ... '"_long sym"@AUTH' ...
8120
- if (Tok.is (AsmToken::String))
8121
- Tokens.resize (2 );
8122
- // ... or '(_sym + 5)@AUTH'.
8123
- else if (Tok.is (AsmToken::LParen))
8124
- Tokens.resize (6 );
8125
- else
8126
- return true ;
8127
-
8128
- if (Parser.getLexer ().peekTokens (Tokens) != Tokens.size ())
8129
- return true ;
8130
-
8131
- // In either case, the expression ends with '@' 'AUTH'.
8132
- if (Tokens[Tokens.size () - 2 ].isNot (AsmToken::At) ||
8133
- Tokens[Tokens.size () - 1 ].isNot (AsmToken::Identifier) ||
8134
- Tokens[Tokens.size () - 1 ].getIdentifier () != " AUTH" )
8135
- return true ;
8136
-
8137
- if (Tok.is (AsmToken::String)) {
8138
- StringRef SymName;
8139
- if (Parser.parseIdentifier (SymName))
8140
- return true ;
8141
- Res = MCSymbolRefExpr::create (Ctx.getOrCreateSymbol (SymName), Ctx);
8142
- } else {
8143
- if (Parser.parsePrimaryExpr (Res, EndLoc, nullptr ))
8144
- return true ;
8145
- }
8146
-
8147
- Parser.Lex (); // '@'
8148
- Parser.Lex (); // 'AUTH'
8149
- }
8150
-
8151
8155
// At this point, we encountered "<id>@AUTH". There is no fallback anymore.
8152
8156
if (parseToken (AsmToken::LParen, " expected '('" ))
8153
8157
return true ;
0 commit comments