implement .include in the lexer/parser instead of passing it into the streamer.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75896 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp
index 7b744fb..6ee9145 100644
--- a/tools/llvm-mc/AsmLexer.cpp
+++ b/tools/llvm-mc/AsmLexer.cpp
@@ -54,6 +54,21 @@
   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 @@
       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 6360b12..5d59d0a 100644
--- a/tools/llvm-mc/AsmLexer.h
+++ b/tools/llvm-mc/AsmLexer.h
@@ -97,6 +97,9 @@
   
   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 cb21a93..68eb9d5 100644
--- a/tools/llvm-mc/AsmParser.cpp
+++ b/tools/llvm-mc/AsmParser.cpp
@@ -1168,21 +1168,27 @@
 /// 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;
 }