diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 8daa2464821..b8f1b2659d8 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -160,12 +160,6 @@ namespace llvm { /// @param AbortReason - The reason assembly is terminated, if non-NULL. virtual void AbortAssembly(const char *AbortReason) = 0; - /// SwitchInputAssemblyFile - Assemble the contents of the specified file in - /// @param FileName at this point in the assembly. - /// - /// @param FileName - The file to assemble at this point - virtual void SwitchInputAssemblyFile(const char *FileName) = 0; - /// DumpSymbolsandMacros - Dump to the specified file in @param FileName all /// symbols and macros at this point in the assembly. /// diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 8ce3325c66f..691694978d4 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -57,8 +57,6 @@ namespace { virtual void AbortAssembly(const char *AbortReason = NULL); - virtual void SwitchInputAssemblyFile(const char *FileName); - virtual void DumpSymbolsandMacros(const char *FileName); virtual void LoadSymbolsandMacros(const char *FileName); @@ -143,10 +141,6 @@ void MCAsmStreamer::AbortAssembly(const char *AbortReason) { } -void MCAsmStreamer::SwitchInputAssemblyFile(const char *FileName) { - OS << ".include" << ' ' << FileName << '\n'; -} - void MCAsmStreamer::DumpSymbolsandMacros(const char *FileName) { OS << ".dump" << ' ' << FileName << '\n'; } diff --git a/test/MC/AsmParser/directive_include.s b/test/MC/AsmParser/directive_include.s index 8c35d2a142a..2721fee035e 100644 --- a/test/MC/AsmParser/directive_include.s +++ b/test/MC/AsmParser/directive_include.s @@ -1,8 +1,9 @@ -# RUN: llvm-mc %s | FileCheck %s +# RUN: llvm-mc %s -I %p | FileCheck %s +# CHECK: TESTA: # CHECK: TEST0: -# CHECK: .include "some/include/file" -# CHECK: .include "mary had a little lamb" -TEST0: - .include "some/include/file" - .include "mary had a little lamb" +# CHECK: .set a, 0 +# CHECK: TESTB: +TESTA: + .include "directive_set.s" +TESTB: diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp index 7b744fbde65..6ee91455b71 100644 --- a/tools/llvm-mc/AsmLexer.cpp +++ b/tools/llvm-mc/AsmLexer.cpp @@ -54,6 +54,21 @@ asmtok::TokKind AsmLexer::ReturnError(const char *Loc, const std::string &Msg) { return asmtok::Error; } +/// EnterIncludeFile - Enter the specified file. This prints an error and +/// returns true on failure. +bool AsmLexer::EnterIncludeFile(const std::string &Filename) { + int NewBuf = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr)); + if (NewBuf == -1) + return true; + + // Save the line number and lex buffer of the includer. + CurBuffer = NewBuf; + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); + CurPtr = CurBuf->getBufferStart(); + return false; +} + + int AsmLexer::getNextChar() { char CurChar = *CurPtr++; switch (CurChar) { @@ -72,6 +87,10 @@ int AsmLexer::getNextChar() { CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc); CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); CurPtr = ParentIncludeLoc.getPointer(); + + // Reset the token start pointer to the start of the new file. + TokStart = CurPtr; + return getNextChar(); } diff --git a/tools/llvm-mc/AsmLexer.h b/tools/llvm-mc/AsmLexer.h index 6360b1280ce..5d59d0ad775 100644 --- a/tools/llvm-mc/AsmLexer.h +++ b/tools/llvm-mc/AsmLexer.h @@ -97,6 +97,9 @@ public: SMLoc getLoc() const; + /// EnterIncludeFile - Enter the specified file. This returns true on failure. + bool EnterIncludeFile(const std::string &Filename); + void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const; private: diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index cb21a93bb1d..68eb9d56c07 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -1168,21 +1168,27 @@ bool AsmParser::ParseDirectiveDarwinLsym() { /// ParseDirectiveInclude /// ::= .include "filename" bool AsmParser::ParseDirectiveInclude() { - const char *Str; - if (Lexer.isNot(asmtok::String)) return TokError("expected string in '.include' directive"); - Str = Lexer.getCurStrVal(); - + std::string Filename = Lexer.getCurStrVal(); + SMLoc IncludeLoc = Lexer.getLoc(); Lexer.Lex(); if (Lexer.isNot(asmtok::EndOfStatement)) return TokError("unexpected token in '.include' directive"); - Lexer.Lex(); - - Out.SwitchInputAssemblyFile(Str); + // Strip the quotes. + Filename = Filename.substr(1, Filename.size()-2); + + // Attempt to switch the lexer to the included file before consuming the end + // of statement to avoid losing it when we switch. + if (Lexer.EnterIncludeFile(Filename)) { + Lexer.PrintMessage(IncludeLoc, + "Could not find include file '" + Filename + "'", + "error"); + return true; + } return false; }