/// \brief Helper class for storing information about an active macro
/// instantiation.
struct MacroInstantiation {
- /// The macro being instantiated.
- const MCAsmMacro *TheMacro;
-
- /// The macro instantiation with substitutions.
- MemoryBuffer *Instantiation;
-
/// The location of the instantiation.
SMLoc InstantiationLoc;
/// The location where parsing should resume upon instantiation completion.
SMLoc ExitLoc;
+ /// The depth of TheCondStack at the start of the instantiation.
+ size_t CondStackDepth;
+
public:
- MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, SMLoc EL,
- MemoryBuffer *I);
+ MacroInstantiation(SMLoc IL, int EB, SMLoc EL, StringRef I,
+ size_t CondStackDepth);
};
struct ParseStatementInfo {
DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE,
DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE,
- DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
+ DK_MACROS_ON, DK_MACROS_OFF,
+ DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
DK_SLEB128, DK_ULEB128,
- DK_ERR, DK_ERROR,
+ DK_ERR, DK_ERROR, DK_WARNING,
DK_END
};
// macro directives
bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
+ bool parseDirectiveExitMacro(StringRef Directive);
bool parseDirectiveEndMacro(StringRef Directive);
bool parseDirectiveMacro(SMLoc DirectiveLoc);
bool parseDirectiveMacrosOnOff(StringRef Directive);
// ".err" or ".error"
bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage);
+ // ".warning"
+ bool parseDirectiveWarning(SMLoc DirectiveLoc);
+
void initializeDirectiveKindMap();
};
}
return parseDirectiveMacrosOnOff(IDVal);
case DK_MACRO:
return parseDirectiveMacro(IDLoc);
+ case DK_EXITM:
+ return parseDirectiveExitMacro(IDVal);
case DK_ENDM:
case DK_ENDMACRO:
return parseDirectiveEndMacro(IDVal);
return parseDirectiveError(IDLoc, false);
case DK_ERROR:
return parseDirectiveError(IDLoc, true);
+ case DK_WARNING:
+ return parseDirectiveWarning(IDLoc);
}
return Error(IDLoc, "unknown directive");
// If parsing succeeded, match the instruction.
if (!HadError) {
- unsigned ErrorInfo;
+ uint64_t ErrorInfo;
getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
Info.ParsedOperands, Out,
ErrorInfo, ParsingInlineAsm);
return false;
}
-MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB,
- SMLoc EL, MemoryBuffer *I)
- : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB),
- ExitLoc(EL) {}
+MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
+ StringRef I, size_t CondStackDepth)
+ : InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
+ CondStackDepth(CondStackDepth) {}
static bool isOperator(AsmToken::TokenKind kind) {
switch (kind) {
// Create the macro instantiation object and add to the current macro
// instantiation stack.
- MacroInstantiation *MI = new MacroInstantiation(
- M, NameLoc, CurBuffer, getTok().getLoc(), Instantiation);
+ MacroInstantiation *MI =
+ new MacroInstantiation(NameLoc, CurBuffer, getTok().getLoc(),
+ Instantiation->getBuffer(), TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
- CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
+ CurBuffer = SrcMgr.AddNewSourceBuffer(Instantiation, SMLoc());
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
Lex();
if (Qualifier == "req")
Parameter.Required = true;
- else if (Qualifier == "vararg" && !IsDarwin)
+ else if (Qualifier == "vararg")
Parameter.Vararg = true;
else
return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
"found in body which will have no effect");
}
+/// parseDirectiveExitMacro
+/// ::= .exitm
+bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Directive + "' directive");
+
+ if (!isInsideMacroInstantiation())
+ return TokError("unexpected '" + Directive + "' in file, "
+ "no current macro definition");
+
+ // Exit all conditionals that are active in the current macro.
+ while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
+ TheCondState = TheCondStack.back();
+ TheCondStack.pop_back();
+ }
+
+ handleMacroExit();
+ return false;
+}
+
/// parseDirectiveEndMacro
/// ::= .endm
/// ::= .endmacro
return true;
}
+/// parseDirectiveWarning
+/// ::= .warning [string]
+bool AsmParser::parseDirectiveWarning(SMLoc L) {
+ if (!TheCondStack.empty()) {
+ if (TheCondStack.back().Ignore) {
+ eatToEndOfStatement();
+ return false;
+ }
+ }
+
+ StringRef Message = ".warning directive invoked in source file";
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::String)) {
+ TokError(".warning argument must be a string");
+ eatToEndOfStatement();
+ return true;
+ }
+
+ Message = getTok().getStringContents();
+ Lex();
+ }
+
+ Warning(L, Message);
+ return false;
+}
+
/// parseDirectiveEndIf
/// ::= .endif
bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
+ DirectiveKindMap[".exitm"] = DK_EXITM;
DirectiveKindMap[".endm"] = DK_ENDM;
DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
DirectiveKindMap[".purgem"] = DK_PURGEM;
DirectiveKindMap[".err"] = DK_ERR;
DirectiveKindMap[".error"] = DK_ERROR;
+ DirectiveKindMap[".warning"] = DK_WARNING;
}
MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
// Create the macro instantiation object and add to the current macro
// instantiation stack.
- MacroInstantiation *MI = new MacroInstantiation(
- M, DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation);
+ MacroInstantiation *MI =
+ new MacroInstantiation(DirectiveLoc, CurBuffer, getTok().getLoc(),
+ Instantiation->getBuffer(), TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
- CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
+ CurBuffer = SrcMgr.AddNewSourceBuffer(Instantiation, SMLoc());
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
Lex();
}