First step in supporting #line directives in assembler. This step parses the
authorKevin Enderby <enderby@apple.com>
Tue, 13 Sep 2011 23:45:18 +0000 (23:45 +0000)
committerKevin Enderby <enderby@apple.com>
Tue, 13 Sep 2011 23:45:18 +0000 (23:45 +0000)
#line directives with the needed support in the lexer.  Next will be to build
a simple file/line# table mapping source SMLoc's for later use by diagnostics.
And the last step will be to get the diagnostics to use the mapping for file
and line numbers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139669 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCParser/AsmLexer.h
lib/MC/MCParser/AsmLexer.cpp
lib/MC/MCParser/AsmParser.cpp

index ab78799fdcd280216c86d4f3171cb97f12a7c7c1..b1277ec6ef031a04538955d4abb4c4a37d1d4cec 100644 (file)
@@ -47,6 +47,7 @@ public:
   void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
 
   virtual StringRef LexUntilEndOfStatement();
+  StringRef LexUntilEndOfLine();
 
   bool isAtStartOfComment(char Char);
   bool isAtStatementSeparator(const char *Ptr);
index bbb0bbc8b243767a795a30479bd5054e5dc15e1d..9760e4676d8c3655a961113f344f0539c1b681fd 100644 (file)
@@ -334,6 +334,17 @@ StringRef AsmLexer::LexUntilEndOfStatement() {
   return StringRef(TokStart, CurPtr-TokStart);
 }
 
+StringRef AsmLexer::LexUntilEndOfLine() {
+  TokStart = CurPtr;
+
+  while (*CurPtr != '\n' &&
+         *CurPtr != '\r' &&
+         (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
+    ++CurPtr;
+  }
+  return StringRef(TokStart, CurPtr-TokStart);
+}
+
 bool AsmLexer::isAtStartOfComment(char Char) {
   // FIXME: This won't work for multi-character comment indicators like "//".
   return Char == *MAI.getCommentString();
@@ -345,17 +356,26 @@ bool AsmLexer::isAtStatementSeparator(const char *Ptr) {
 }
 
 AsmToken AsmLexer::LexToken() {
+  static bool isAtStartOfLine = true;
   TokStart = CurPtr;
   // This always consumes at least one character.
   int CurChar = getNextChar();
 
-  if (isAtStartOfComment(CurChar))
+  if (isAtStartOfComment(CurChar)) {
+    // If this comment starts with a '#', then return the Hash token and let
+    // the assembler parser see if it can be parsed as a cpp line filename
+    // comment. We do this only if we are at the start of a line.
+    if (CurChar == '#' && isAtStartOfLine)
+      return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
+    isAtStartOfLine = true;
     return LexLineComment();
+  }
   if (isAtStatementSeparator(TokStart)) {
     CurPtr += strlen(MAI.getSeparatorString()) - 1;
     return AsmToken(AsmToken::EndOfStatement,
                     StringRef(TokStart, strlen(MAI.getSeparatorString())));
   }
+  isAtStartOfLine = false;
 
   switch (CurChar) {
   default:
@@ -373,6 +393,7 @@ AsmToken AsmLexer::LexToken() {
     return LexToken();
   case '\n': // FALL THROUGH.
   case '\r':
+    isAtStartOfLine = true;
     return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
   case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
   case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
index cd8d2707a806680130a9c78856d2350d30e92101..5ab7ca6e8306b7008854ea80e33fa80d92cccdf1 100644 (file)
@@ -153,6 +153,8 @@ private:
   void CheckForValidSection();
 
   bool ParseStatement();
+  void EatToEndOfLine();
+  bool ParseCppHashLineFilenameComment(const SMLoc &L);
 
   bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M);
   bool expandMacro(SmallString<256> &Buf, StringRef Body,
@@ -937,10 +939,8 @@ bool AsmParser::ParseStatement() {
   StringRef IDVal;
   int64_t LocalLabelVal = -1;
   // A full line comment is a '#' as the first token.
-  if (Lexer.is(AsmToken::Hash)) {
-    EatToEndOfStatement();
-    return false;
-  }
+  if (Lexer.is(AsmToken::Hash))
+    return ParseCppHashLineFilenameComment(IDLoc);
 
   // Allow an integer followed by a ':' as a directional local label.
   if (Lexer.is(AsmToken::Integer)) {
@@ -1209,6 +1209,49 @@ bool AsmParser::ParseStatement() {
   return false;
 }
 
+/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line
+/// since they may not be able to be tokenized to get to the end of line token.
+void AsmParser::EatToEndOfLine() {
+ Lexer.LexUntilEndOfLine();
+ // Eat EOL.
+ Lex();
+}
+
+/// ParseCppHashLineFilenameComment as this:
+///   ::= # number "filename"
+/// or just as a full line comment if it doesn't have a number and a string.
+bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) {
+  Lex(); // Eat the hash token.
+
+  if (getLexer().isNot(AsmToken::Integer)) {
+    // Consume the line since in cases it is not a well-formed line directive,
+    // as if were simply a full line comment.
+    EatToEndOfLine();
+    return false;
+  }
+
+  int64_t LineNumber = getTok().getIntVal();
+  // FIXME: remember to remove this line that is silencing a warning for now.
+  (void) LineNumber;
+  Lex();
+
+  if (getLexer().isNot(AsmToken::String)) {
+    EatToEndOfLine();
+    return false;
+  }
+
+  StringRef Filename = getTok().getString();
+  // Get rid of the enclosing quotes.
+  Filename = Filename.substr(1, Filename.size()-2);
+
+  // TODO: Now with the Filename, LineNumber set up a mapping to the SMLoc for
+  // later use by diagnostics.
+
+  // Ignore any trailing characters, they're just comment.
+  EatToEndOfLine();
+  return false;
+}
+
 bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
                             const std::vector<StringRef> &Parameters,
                             const std::vector<std::vector<AsmToken> > &A,