From f29ce975ba6d4b2f1cb9a54f049921eb688c8979 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 22 Feb 2011 13:49:06 +0000 Subject: [PATCH] Reimplement __pragma support using a TokenLexer llvm-svn: 126221 --- clang/include/clang/Lex/Preprocessor.h | 3 -- clang/lib/Lex/PPDirectives.cpp | 1 + clang/lib/Lex/Pragma.cpp | 67 ++++++++++++-------------- 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 018f7e9c8c02..9005adc6ade6 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -942,9 +942,6 @@ private: /// is not enclosed within a string literal. void HandleMicrosoft__pragma(Token &Tok); - void Handle_Pragma(unsigned Introducer, const std::string &StrVal, - SourceLocation PragmaLoc, SourceLocation RParenLoc); - /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and /// start lexing tokens from it instead of the current buffer. void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir); diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index f92fa038a30c..3e871ae7ab47 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -86,6 +86,7 @@ void Preprocessor::DiscardUntilEndOfDirective() { Token Tmp; do { LexUnexpandedToken(Tmp); + assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens"); } while (Tmp.isNot(tok::eom)); } diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index 31e777604ebe..80d3bb1d2790 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -175,7 +175,22 @@ void Preprocessor::Handle_Pragma(Token &Tok) { } } - Handle_Pragma(PIK__Pragma, StrVal, PragmaLoc, RParenLoc); + // Plop the string (including the newline and trailing null) into a buffer + // where we can lex it. + Token TmpTok; + TmpTok.startToken(); + CreateString(&StrVal[0], StrVal.size(), TmpTok); + SourceLocation TokLoc = TmpTok.getLocation(); + + // Make and enter a lexer object so that we lex and expand the tokens just + // like any others. + Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc, + StrVal.size(), *this); + + EnterSourceFileWithLexer(TL, 0); + + // With everything set up, lex this as a #pragma directive. + HandlePragmaDirective(PIK__Pragma); // Finally, return whatever came after the pragma directive. return Lex(Tok); @@ -194,16 +209,16 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) { return; } - // Get the tokens enclosed within the __pragma(). + // Get the tokens enclosed within the __pragma(), as well as the final ')'. llvm::SmallVector PragmaToks; int NumParens = 0; Lex(Tok); while (Tok.isNot(tok::eof)) { + PragmaToks.push_back(Tok); if (Tok.is(tok::l_paren)) NumParens++; else if (Tok.is(tok::r_paren) && NumParens-- == 0) break; - PragmaToks.push_back(Tok); Lex(Tok); } @@ -212,46 +227,24 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) { return; } - // Build the pragma string. - std::string StrVal = " "; - for (llvm::SmallVector::iterator I = - PragmaToks.begin(), E = PragmaToks.end(); I != E; ++I) { - StrVal += getSpelling(*I); - } - - SourceLocation RParenLoc = Tok.getLocation(); + PragmaToks.front().setFlag(Token::LeadingSpace); - Handle_Pragma(PIK___pragma, StrVal, PragmaLoc, RParenLoc); + // Replace the ')' with an EOM to mark the end of the pragma. + PragmaToks.back().setKind(tok::eom); + + Token *TokArray = new Token[PragmaToks.size()]; + std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray); + + // Push the tokens onto the stack. + EnterTokenStream(TokArray, PragmaToks.size(), true, true); + + // With everything set up, lex this as a #pragma directive. + HandlePragmaDirective(PIK___pragma); // Finally, return whatever came after the pragma directive. return Lex(Tok); } -void Preprocessor::Handle_Pragma(unsigned Introducer, - const std::string &StrVal, - SourceLocation PragmaLoc, - SourceLocation RParenLoc) { - - // Plop the string (including the newline and trailing null) into a buffer - // where we can lex it. - Token TmpTok; - TmpTok.startToken(); - CreateString(&StrVal[0], StrVal.size(), TmpTok); - SourceLocation TokLoc = TmpTok.getLocation(); - - // Make and enter a lexer object so that we lex and expand the tokens just - // like any others. - Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc, - StrVal.size(), *this); - - EnterSourceFileWithLexer(TL, 0); - - // With everything set up, lex this as a #pragma directive. - HandlePragmaDirective(Introducer); -} - - - /// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'. /// void Preprocessor::HandlePragmaOnce(Token &OnceTok) {