/// @param AbortReason - The reason assembly is terminated, if non-NULL.
virtual void AbortAssembly(const char *AbortReason) = 0;
/// @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.
///
/// DumpSymbolsandMacros - Dump to the specified file in @param FileName all
/// symbols and macros at this point in the assembly.
///
virtual void AbortAssembly(const char *AbortReason = NULL);
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);
virtual void DumpSymbolsandMacros(const char *FileName);
virtual void LoadSymbolsandMacros(const char *FileName);
-void MCAsmStreamer::SwitchInputAssemblyFile(const char *FileName) {
- OS << ".include" << ' ' << FileName << '\n';
-}
-
void MCAsmStreamer::DumpSymbolsandMacros(const char *FileName) {
OS << ".dump" << ' ' << FileName << '\n';
}
void MCAsmStreamer::DumpSymbolsandMacros(const char *FileName) {
OS << ".dump" << ' ' << FileName << '\n';
}
-# RUN: llvm-mc %s | FileCheck %s
+# RUN: llvm-mc %s -I %p | FileCheck %s
-# 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:
+/// 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) {
int AsmLexer::getNextChar() {
char CurChar = *CurPtr++;
switch (CurChar) {
CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
CurPtr = ParentIncludeLoc.getPointer();
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;
+
+ /// 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:
void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
private:
/// ParseDirectiveInclude
/// ::= .include "filename"
bool AsmParser::ParseDirectiveInclude() {
/// ParseDirectiveInclude
/// ::= .include "filename"
bool AsmParser::ParseDirectiveInclude() {
if (Lexer.isNot(asmtok::String))
return TokError("expected string in '.include' directive");
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();
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;
+ }