diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp index f29075ace48..cf6a4a8c124 100644 --- a/tools/llvm-mc/AsmLexer.cpp +++ b/tools/llvm-mc/AsmLexer.cpp @@ -84,7 +84,7 @@ asmtok::TokKind AsmLexer::LexIdentifier() { /// LexPercent: Register: %[a-zA-Z0-9]+ asmtok::TokKind AsmLexer::LexPercent() { if (!isalnum(*CurPtr)) - return asmtok::Error; // Must have at least one character. + return ReturnError(TokStart, "invalid register name"); while (isalnum(*CurPtr)) ++CurPtr; CurStrVal.assign(TokStart, CurPtr); // Skip % @@ -103,8 +103,7 @@ asmtok::TokKind AsmLexer::LexSlash() { int CurChar = getNextChar(); switch (CurChar) { case EOF: - PrintError(TokStart, "Unterminated comment!"); - return asmtok::Error; + return ReturnError(TokStart, "unterminated comment"); case '*': // End of the comment? if (CurPtr[0] != '/') break; @@ -137,9 +136,9 @@ asmtok::TokKind AsmLexer::LexHash() { /// TODO: FP literal. asmtok::TokKind AsmLexer::LexDigit() { if (*CurPtr == ':') - return asmtok::Error; // FIXME LOCAL LABEL. + return ReturnError(TokStart, "FIXME: local label not implemented"); if (*CurPtr == 'f' || *CurPtr == 'b') - return asmtok::Error; // FIXME FORWARD/BACKWARD LABEL. + return ReturnError(TokStart, "FIXME: directional label not implemented"); // Decimal integer: [1-9][0-9]* if (CurPtr[-1] != '0') { @@ -229,7 +228,7 @@ asmtok::TokKind AsmLexer::LexToken() { return LexIdentifier(); // Unknown character, emit an error. - return asmtok::Error; + return ReturnError(TokStart, "invalid character in input"); case EOF: return asmtok::Eof; case 0: case ' ': diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp new file mode 100644 index 00000000000..abb0d35b086 --- /dev/null +++ b/tools/llvm-mc/AsmParser.cpp @@ -0,0 +1,19 @@ +//===- AsmParser.cpp - Parser for Assembly Files --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class implements the parser for assembly files. +// +//===----------------------------------------------------------------------===// + +#include "AsmParser.h" +using namespace llvm; + +bool AsmParser::Run() { + return false; +} diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h new file mode 100644 index 00000000000..adcd74c7a51 --- /dev/null +++ b/tools/llvm-mc/AsmParser.h @@ -0,0 +1,34 @@ +//===- AsmParser.h - Parser for Assembly Files ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class declares the parser for assembly files. +// +//===----------------------------------------------------------------------===// + +#ifndef ASMPARSER_H +#define ASMPARSER_H + +#include "AsmLexer.h" + +namespace llvm { + +class AsmParser { + AsmLexer Lexer; + +public: + AsmParser(SourceMgr &SM) : Lexer(SM) {} + ~AsmParser() {} + + bool Run(); + +}; + +} // end namespace llvm + +#endif diff --git a/tools/llvm-mc/CMakeLists.txt b/tools/llvm-mc/CMakeLists.txt index b71fa5493f0..d8195e7418c 100644 --- a/tools/llvm-mc/CMakeLists.txt +++ b/tools/llvm-mc/CMakeLists.txt @@ -3,4 +3,5 @@ set(LLVM_LINK_COMPONENTS support) add_llvm_tool(llvm-mc llvm-mc.cpp AsmLexer.cpp + AsmParser.cpp ) diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 7a179e83ff6..0acd78ea41d 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -19,7 +19,7 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Signals.h" -#include "AsmLexer.h" +#include "AsmParser.h" using namespace llvm; static cl::opt @@ -34,16 +34,20 @@ IncludeDirs("I", cl::desc("Directory of include files"), cl::value_desc("directory"), cl::Prefix); enum ActionType { + AC_AsLex, AC_Assemble }; static cl::opt Action(cl::desc("Action to perform:"), - cl::values(clEnumValN(AC_Assemble, "assemble", + cl::init(AC_Assemble), + cl::values(clEnumValN(AC_AsLex, "as-lex", + "Lex tokens from a .s file"), + clEnumValN(AC_Assemble, "assemble", "Assemble a .s file (default)"), clEnumValEnd)); -static int AssembleInput(const char *ProgName) { +static int AsLexInput(const char *ProgName) { std::string ErrorMessage; MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage); @@ -65,16 +69,19 @@ static int AssembleInput(const char *ProgName) { // it later. SrcMgr.setIncludeDirs(IncludeDirs); - - AsmLexer Lexer(SrcMgr); + bool Error = false; + asmtok::TokKind Tok = Lexer.Lex(); while (Tok != asmtok::Eof) { switch (Tok) { - default: Lexer.PrintError(Lexer.getLoc(), "driver: unknown token"); break; + default: + Lexer.PrintError(Lexer.getLoc(), "driver: unknown token"); + Error = true; + break; case asmtok::Error: - Lexer.PrintError(Lexer.getLoc(), "error, bad token"); + Error = true; // error already printed. break; case asmtok::Identifier: outs() << "identifier: " << Lexer.getCurStrVal() << '\n'; @@ -103,9 +110,35 @@ static int AssembleInput(const char *ProgName) { Tok = Lexer.Lex(); } - return 1; + return Error; } +static int AssembleInput(const char *ProgName) { + std::string ErrorMessage; + MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, + &ErrorMessage); + if (Buffer == 0) { + errs() << ProgName << ": "; + if (ErrorMessage.size()) + errs() << ErrorMessage << "\n"; + else + errs() << "input file didn't read correctly.\n"; + return 1; + } + + SourceMgr SrcMgr; + + // Tell SrcMgr about this buffer, which is what TGParser will pick up. + SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); + + // Record the location of the include directories so that the lexer can find + // it later. + SrcMgr.setIncludeDirs(IncludeDirs); + + AsmParser Parser(SrcMgr); + return Parser.Run(); +} + int main(int argc, char **argv) { // Print a stack trace if we signal out. @@ -116,6 +149,8 @@ int main(int argc, char **argv) { switch (Action) { default: + case AC_AsLex: + return AsLexInput(argv[0]); case AC_Assemble: return AssembleInput(argv[0]); }