Reimplement __pragma support using a TokenLexer

llvm-svn: 126221
This commit is contained in:
Peter Collingbourne 2011-02-22 13:49:06 +00:00
parent 2c9f966600
commit f29ce975ba
3 changed files with 31 additions and 40 deletions

View File

@ -942,9 +942,6 @@ private:
/// is not enclosed within a string literal. /// is not enclosed within a string literal.
void HandleMicrosoft__pragma(Token &Tok); 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 /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
/// start lexing tokens from it instead of the current buffer. /// start lexing tokens from it instead of the current buffer.
void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir); void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);

View File

@ -86,6 +86,7 @@ void Preprocessor::DiscardUntilEndOfDirective() {
Token Tmp; Token Tmp;
do { do {
LexUnexpandedToken(Tmp); LexUnexpandedToken(Tmp);
assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens");
} while (Tmp.isNot(tok::eom)); } while (Tmp.isNot(tok::eom));
} }

View File

@ -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. // Finally, return whatever came after the pragma directive.
return Lex(Tok); return Lex(Tok);
@ -194,16 +209,16 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
return; return;
} }
// Get the tokens enclosed within the __pragma(). // Get the tokens enclosed within the __pragma(), as well as the final ')'.
llvm::SmallVector<Token, 32> PragmaToks; llvm::SmallVector<Token, 32> PragmaToks;
int NumParens = 0; int NumParens = 0;
Lex(Tok); Lex(Tok);
while (Tok.isNot(tok::eof)) { while (Tok.isNot(tok::eof)) {
PragmaToks.push_back(Tok);
if (Tok.is(tok::l_paren)) if (Tok.is(tok::l_paren))
NumParens++; NumParens++;
else if (Tok.is(tok::r_paren) && NumParens-- == 0) else if (Tok.is(tok::r_paren) && NumParens-- == 0)
break; break;
PragmaToks.push_back(Tok);
Lex(Tok); Lex(Tok);
} }
@ -212,46 +227,24 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
return; return;
} }
// Build the pragma string. PragmaToks.front().setFlag(Token::LeadingSpace);
std::string StrVal = " ";
for (llvm::SmallVector<Token, 32>::iterator I =
PragmaToks.begin(), E = PragmaToks.end(); I != E; ++I) {
StrVal += getSpelling(*I);
}
SourceLocation RParenLoc = Tok.getLocation(); // Replace the ')' with an EOM to mark the end of the pragma.
PragmaToks.back().setKind(tok::eom);
Handle_Pragma(PIK___pragma, StrVal, PragmaLoc, RParenLoc); 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. // Finally, return whatever came after the pragma directive.
return Lex(Tok); 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'. /// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
/// ///
void Preprocessor::HandlePragmaOnce(Token &OnceTok) { void Preprocessor::HandlePragmaOnce(Token &OnceTok) {