[llvm-commits] [llvm] r108652 - in /llvm/trunk: lib/MC/MCParser/AsmParser.cpp test/MC/AsmParser/macros-parsing.s
Daniel Dunbar
daniel at zuster.org
Sun Jul 18 11:47:21 PDT 2010
Author: ddunbar
Date: Sun Jul 18 13:47:21 2010
New Revision: 108652
URL: http://llvm.org/viewvc/llvm-project?rev=108652&view=rev
Log:
MC/AsmParser: Add basic parsing support for .macro definitions.
Modified:
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/test/MC/AsmParser/macros-parsing.s
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=108652&r1=108651&r2=108652&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Sun Jul 18 13:47:21 2010
@@ -36,6 +36,15 @@
namespace {
+/// \brief Helper class for tracking macro definitions.
+struct Macro {
+ StringRef Name;
+ StringRef Body;
+
+public:
+ Macro(StringRef N, StringRef B) : Name(N), Body(B) {}
+};
+
/// \brief The concrete assembly parser instance.
class AsmParser : public MCAsmParser {
friend class GenericAsmParser;
@@ -63,6 +72,9 @@
/// in the directive name and the location of the directive keyword.
StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap;
+ /// MacroMap - Map of currently defined macros.
+ StringMap<Macro*> MacroMap;
+
/// Boolean tracking whether macro substitution is enabled.
unsigned MacrosEnabled : 1;
@@ -179,12 +191,21 @@
Parser.AddDirectiveHandler(this, ".macros_off",
MCAsmParser::DirectiveHandler(
&GenericAsmParser::ParseDirectiveMacrosOnOff));
+ Parser.AddDirectiveHandler(this, ".macro", MCAsmParser::DirectiveHandler(
+ &GenericAsmParser::ParseDirectiveMacro));
+ Parser.AddDirectiveHandler(this, ".endm", MCAsmParser::DirectiveHandler(
+ &GenericAsmParser::ParseDirectiveEndMacro));
+ Parser.AddDirectiveHandler(this, ".endmacro", MCAsmParser::DirectiveHandler(
+ &GenericAsmParser::ParseDirectiveEndMacro));
}
bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc);
+
bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
};
}
@@ -785,6 +806,17 @@
if (IDVal == ".include")
return ParseDirectiveInclude();
+ // If macros are enabled, check to see if this is a macro instantiation.
+ if (MacrosEnabled) {
+ if (const Macro *M = MacroMap.lookup(IDVal)) {
+ (void) M;
+
+ Error(IDLoc, "macros are not yet supported");
+ EatToEndOfStatement();
+ return false;
+ }
+ }
+
// Look up the handler in the handler table.
std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
DirectiveMap.lookup(IDVal);
@@ -1626,6 +1658,70 @@
return false;
}
+/// ParseDirectiveMacro
+/// ::= .macro name
+bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
+ SMLoc DirectiveLoc) {
+ StringRef Name;
+ if (getParser().ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.macro' directive");
+
+ // Eat the end of statement.
+ Lex();
+
+ AsmToken EndToken, StartToken = getTok();
+
+ // Lex the macro definition.
+ for (;;) {
+ // Check whether we have reached the end of the file.
+ if (getLexer().is(AsmToken::Eof))
+ return Error(DirectiveLoc, "no matching '.endmacro' in definition");
+
+ // Otherwise, check whether we have reach the .endmacro.
+ if (getLexer().is(AsmToken::Identifier) &&
+ (getTok().getIdentifier() == ".endm" ||
+ getTok().getIdentifier() == ".endmacro")) {
+ EndToken = getTok();
+ Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + EndToken.getIdentifier() +
+ "' directive");
+ break;
+ }
+
+ // Otherwise, scan til the end of the statement.
+ getParser().EatToEndOfStatement();
+ }
+
+ if (getParser().MacroMap.lookup(Name)) {
+ return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
+ }
+
+ const char *BodyStart = StartToken.getLoc().getPointer();
+ const char *BodyEnd = EndToken.getLoc().getPointer();
+ StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
+ getParser().MacroMap[Name] = new Macro(Name, Body);
+ return false;
+}
+
+/// ParseDirectiveEndMacro
+/// ::= .endm
+/// ::= .endmacro
+bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
+ SMLoc DirectiveLoc) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Directive + "' directive");
+
+ // If we see a .endmacro directly, it is a stray entry in the file; well
+ // formed .endmacro directives are handled during the macro definition
+ // parsing.
+ return TokError("unexpected '" + Directive + "' in file, "
+ "no current macro definition");
+}
+
/// \brief Create an MCAsmParser instance.
MCAsmParser *llvm::createMCAsmParser(const Target &T, SourceMgr &SM,
MCContext &C, MCStreamer &Out,
Modified: llvm/trunk/test/MC/AsmParser/macros-parsing.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macros-parsing.s?rev=108652&r1=108651&r2=108652&view=diff
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macros-parsing.s (original)
+++ llvm/trunk/test/MC/AsmParser/macros-parsing.s Sun Jul 18 13:47:21 2010
@@ -1,8 +1,23 @@
-// RUN: llvm-mc %s 2> %t.err
+// RUN: not llvm-mc %s 2> %t.err
// RUN: FileCheck --check-prefix=CHECK-ERRORS %s < %t.err
-.macros_on
+.macro .test0
+.endmacro
+
.macros_off
+// CHECK-ERRORS: 9:1: warning: ignoring directive for now
+.test0
+.macros_on
+// CHECK-ERRORS: 12:1: error: macros are not yet supported
+.test0
+
+// CHECK-ERRORS: macro '.test0' is already defined
+.macro .test0
+.endmacro
+
+// CHECK-ERRORS: unexpected '.endmacro' in file
+.endmacro
+
+// CHECK-ERRORS: no matching '.endmacro' in definition
+.macro dummy
-// CHECK-ERRORS: .abort '"end"' detected
-.abort "end"
More information about the llvm-commits
mailing list