forked from OSchip/llvm-project
Implement comment saving mode: the -C and -CC options.
llvm-svn: 38783
This commit is contained in:
parent
2be4115465
commit
457fc15bc5
|
@ -99,6 +99,11 @@ static void OutputString(const char *Ptr, unsigned Size) {
|
||||||
|
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
DisableLineMarkers("P", cl::desc("Disable linemarker output in -E mode"));
|
DisableLineMarkers("P", cl::desc("Disable linemarker output in -E mode"));
|
||||||
|
static cl::opt<bool>
|
||||||
|
EnableCommentOutput("C", cl::desc("Enable comment output in -E mode"));
|
||||||
|
static cl::opt<bool>
|
||||||
|
EnableMacroCommentOutput("CC", cl::desc("Enable comment output in -E mode, "
|
||||||
|
"even from macro expansions"));
|
||||||
|
|
||||||
static unsigned EModeCurLine;
|
static unsigned EModeCurLine;
|
||||||
static std::string EModeCurFilename;
|
static std::string EModeCurFilename;
|
||||||
|
@ -357,7 +362,12 @@ static bool AvoidConcat(const LexerToken &PrevTok, const LexerToken &Tok,
|
||||||
|
|
||||||
/// DoPrintPreprocessedInput - This implements -E mode.
|
/// DoPrintPreprocessedInput - This implements -E mode.
|
||||||
///
|
///
|
||||||
void clang::DoPrintPreprocessedInput(Preprocessor &PP) {
|
void clang::DoPrintPreprocessedInput(Preprocessor &PP, LangOptions &Options) {
|
||||||
|
if (EnableCommentOutput) // -C specified?
|
||||||
|
Options.KeepComments = 1;
|
||||||
|
if (EnableMacroCommentOutput) // -CC specified?
|
||||||
|
Options.KeepComments = Options.KeepMacroComments = 1;
|
||||||
|
|
||||||
InitOutputBuffer();
|
InitOutputBuffer();
|
||||||
|
|
||||||
LexerToken Tok, PrevTok;
|
LexerToken Tok, PrevTok;
|
||||||
|
|
|
@ -703,7 +703,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case PrintPreprocessedInput: // -E mode.
|
case PrintPreprocessedInput: // -E mode.
|
||||||
DoPrintPreprocessedInput(PP);
|
DoPrintPreprocessedInput(PP, Options);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DumpTokens: { // Token dump mode.
|
case DumpTokens: { // Token dump mode.
|
||||||
|
|
|
@ -16,10 +16,11 @@
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class Preprocessor;
|
class Preprocessor;
|
||||||
|
class LangOptions;
|
||||||
|
|
||||||
/// DoPrintPreprocessedInput - Implement -E mode.
|
/// DoPrintPreprocessedInput - Implement -E mode.
|
||||||
void DoPrintPreprocessedInput(Preprocessor &PP);
|
void DoPrintPreprocessedInput(Preprocessor &PP, LangOptions &Options);
|
||||||
|
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
|
@ -65,6 +65,9 @@ Lexer::Lexer(const SourceBuffer *File, unsigned fileid, Preprocessor &pp,
|
||||||
// to quickly lex the tokens of the buffer, e.g. when handling a "#if 0" block
|
// to quickly lex the tokens of the buffer, e.g. when handling a "#if 0" block
|
||||||
// or otherwise skipping over tokens.
|
// or otherwise skipping over tokens.
|
||||||
LexingRawMode = false;
|
LexingRawMode = false;
|
||||||
|
|
||||||
|
// Default to keeping comments if requested.
|
||||||
|
KeepCommentMode = Features.KeepComments;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stringify - Convert the specified string into a C string, with surrounding
|
/// Stringify - Convert the specified string into a C string, with surrounding
|
||||||
|
@ -587,13 +590,15 @@ void Lexer::SkipWhitespace(LexerToken &Result, const char *CurPtr) {
|
||||||
|
|
||||||
// If the next token is obviously a // or /* */ comment, skip it efficiently
|
// If the next token is obviously a // or /* */ comment, skip it efficiently
|
||||||
// too (without going through the big switch stmt).
|
// too (without going through the big switch stmt).
|
||||||
if (Char == '/' && CurPtr[1] == '/') {
|
if (Char == '/' && CurPtr[1] == '/' && !KeepCommentMode) {
|
||||||
BufferPtr = CurPtr;
|
BufferPtr = CurPtr;
|
||||||
return SkipBCPLComment(Result, CurPtr+1);
|
SkipBCPLComment(Result, CurPtr+1);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (Char == '/' && CurPtr[1] == '*') {
|
if (Char == '/' && CurPtr[1] == '*' && !KeepCommentMode) {
|
||||||
BufferPtr = CurPtr;
|
BufferPtr = CurPtr;
|
||||||
return SkipBlockComment(Result, CurPtr+2);
|
SkipBlockComment(Result, CurPtr+2);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
BufferPtr = CurPtr;
|
BufferPtr = CurPtr;
|
||||||
}
|
}
|
||||||
|
@ -601,7 +606,7 @@ void Lexer::SkipWhitespace(LexerToken &Result, const char *CurPtr) {
|
||||||
// SkipBCPLComment - We have just read the // characters from input. Skip until
|
// SkipBCPLComment - We have just read the // characters from input. Skip until
|
||||||
// we find the newline character thats terminate the comment. Then update
|
// we find the newline character thats terminate the comment. Then update
|
||||||
/// BufferPtr and return.
|
/// BufferPtr and return.
|
||||||
void Lexer::SkipBCPLComment(LexerToken &Result, const char *CurPtr) {
|
bool Lexer::SkipBCPLComment(LexerToken &Result, const char *CurPtr) {
|
||||||
// If BCPL comments aren't explicitly enabled for this language, emit an
|
// If BCPL comments aren't explicitly enabled for this language, emit an
|
||||||
// extension warning.
|
// extension warning.
|
||||||
if (!Features.BCPLComment) {
|
if (!Features.BCPLComment) {
|
||||||
|
@ -648,16 +653,20 @@ void Lexer::SkipBCPLComment(LexerToken &Result, const char *CurPtr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurPtr == BufferEnd+1) goto FoundEOF;
|
if (CurPtr == BufferEnd+1) { --CurPtr; break; }
|
||||||
} while (C != '\n' && C != '\r');
|
} while (C != '\n' && C != '\r');
|
||||||
|
|
||||||
// Found and did not consume a newline.
|
// Found but did not consume the newline.
|
||||||
|
|
||||||
|
// If we are returning comments as tokens, return this comment as a token.
|
||||||
|
if (KeepCommentMode)
|
||||||
|
return SaveBCPLComment(Result, CurPtr);
|
||||||
|
|
||||||
// If we are inside a preprocessor directive and we see the end of line,
|
// If we are inside a preprocessor directive and we see the end of line,
|
||||||
// return immediately, so that the lexer can return this as an EOM token.
|
// return immediately, so that the lexer can return this as an EOM token.
|
||||||
if (ParsingPreprocessorDirective) {
|
if (ParsingPreprocessorDirective || CurPtr == BufferEnd) {
|
||||||
BufferPtr = CurPtr;
|
BufferPtr = CurPtr;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, eat the \n character. We don't care if this is a \n\r or
|
// Otherwise, eat the \n character. We don't care if this is a \n\r or
|
||||||
|
@ -674,15 +683,33 @@ void Lexer::SkipBCPLComment(LexerToken &Result, const char *CurPtr) {
|
||||||
// big switch, handle it efficiently now.
|
// big switch, handle it efficiently now.
|
||||||
if (isWhitespace(*CurPtr)) {
|
if (isWhitespace(*CurPtr)) {
|
||||||
Result.SetFlag(LexerToken::LeadingSpace);
|
Result.SetFlag(LexerToken::LeadingSpace);
|
||||||
return SkipWhitespace(Result, CurPtr+1);
|
SkipWhitespace(Result, CurPtr+1);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferPtr = CurPtr;
|
BufferPtr = CurPtr;
|
||||||
return;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
FoundEOF: // If we ran off the end of the buffer, return EOF.
|
/// SaveBCPLComment - If in save-comment mode, package up this BCPL comment in
|
||||||
BufferPtr = CurPtr-1;
|
/// an appropriate way and return it.
|
||||||
return;
|
bool Lexer::SaveBCPLComment(LexerToken &Result, const char *CurPtr) {
|
||||||
|
Result.SetKind(tok::comment);
|
||||||
|
FormTokenWithChars(Result, CurPtr);
|
||||||
|
|
||||||
|
// If this BCPL-style comment is in a macro definition, transmogrify it into
|
||||||
|
// a C-style block comment.
|
||||||
|
if (ParsingPreprocessorDirective) {
|
||||||
|
std::string Spelling = PP.getSpelling(Result);
|
||||||
|
assert(Spelling[0] == '/' && Spelling[1] == '/' && "Not bcpl comment?");
|
||||||
|
Spelling[1] = '*'; // Change prefix to "/*".
|
||||||
|
Spelling += "*/"; // add suffix.
|
||||||
|
|
||||||
|
Result.SetLocation(PP.CreateString(&Spelling[0], Spelling.size(),
|
||||||
|
Result.getLocation()));
|
||||||
|
Result.SetLength(Spelling.size());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isBlockCommentEndOfEscapedNewLine - Return true if the specified newline
|
/// isBlockCommentEndOfEscapedNewLine - Return true if the specified newline
|
||||||
|
@ -748,7 +775,7 @@ static bool isEndOfBlockCommentWithEscapedNewLine(const char *CurPtr,
|
||||||
/// because they cannot cause the comment to end. The only thing that can
|
/// because they cannot cause the comment to end. The only thing that can
|
||||||
/// happen is the comment could end with an escaped newline between the */ end
|
/// happen is the comment could end with an escaped newline between the */ end
|
||||||
/// of comment.
|
/// of comment.
|
||||||
void Lexer::SkipBlockComment(LexerToken &Result, const char *CurPtr) {
|
bool Lexer::SkipBlockComment(LexerToken &Result, const char *CurPtr) {
|
||||||
// Scan one character past where we should, looking for a '/' character. Once
|
// Scan one character past where we should, looking for a '/' character. Once
|
||||||
// we find it, check to see if it was preceeded by a *. This common
|
// we find it, check to see if it was preceeded by a *. This common
|
||||||
// optimization helps people who like to put a lot of * characters in their
|
// optimization helps people who like to put a lot of * characters in their
|
||||||
|
@ -757,7 +784,7 @@ void Lexer::SkipBlockComment(LexerToken &Result, const char *CurPtr) {
|
||||||
if (C == 0 && CurPtr == BufferEnd+1) {
|
if (C == 0 && CurPtr == BufferEnd+1) {
|
||||||
Diag(BufferPtr, diag::err_unterminated_block_comment);
|
Diag(BufferPtr, diag::err_unterminated_block_comment);
|
||||||
BufferPtr = CurPtr-1;
|
BufferPtr = CurPtr-1;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -789,22 +816,31 @@ void Lexer::SkipBlockComment(LexerToken &Result, const char *CurPtr) {
|
||||||
// after the /*, but this would involve lexing a lot of what really is the
|
// after the /*, but this would involve lexing a lot of what really is the
|
||||||
// comment, which surely would confuse the parser.
|
// comment, which surely would confuse the parser.
|
||||||
BufferPtr = CurPtr-1;
|
BufferPtr = CurPtr-1;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
C = *CurPtr++;
|
C = *CurPtr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are returning comments as tokens, return this comment as a token.
|
||||||
|
if (KeepCommentMode) {
|
||||||
|
Result.SetKind(tok::comment);
|
||||||
|
FormTokenWithChars(Result, CurPtr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// It is common for the tokens immediately after a /**/ comment to be
|
// It is common for the tokens immediately after a /**/ comment to be
|
||||||
// whitespace. Instead of going through the big switch, handle it
|
// whitespace. Instead of going through the big switch, handle it
|
||||||
// efficiently now.
|
// efficiently now.
|
||||||
if (isHorizontalWhitespace(*CurPtr)) {
|
if (isHorizontalWhitespace(*CurPtr)) {
|
||||||
Result.SetFlag(LexerToken::LeadingSpace);
|
Result.SetFlag(LexerToken::LeadingSpace);
|
||||||
return SkipWhitespace(Result, CurPtr+1);
|
SkipWhitespace(Result, CurPtr+1);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, just return so that the next character will be lexed as a token.
|
// Otherwise, just return so that the next character will be lexed as a token.
|
||||||
BufferPtr = CurPtr;
|
BufferPtr = CurPtr;
|
||||||
Result.SetFlag(LexerToken::LeadingSpace);
|
Result.SetFlag(LexerToken::LeadingSpace);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -920,6 +956,9 @@ bool Lexer::LexEndOfFile(LexerToken &Result, const char *CurPtr) {
|
||||||
Result.SetKind(tok::eom);
|
Result.SetKind(tok::eom);
|
||||||
// Update the location of token as well as BufferPtr.
|
// Update the location of token as well as BufferPtr.
|
||||||
FormTokenWithChars(Result, CurPtr);
|
FormTokenWithChars(Result, CurPtr);
|
||||||
|
|
||||||
|
// Restore comment saving mode, in case it was disabled for directive.
|
||||||
|
KeepCommentMode = Features.KeepComments;
|
||||||
return true; // Have a token.
|
return true; // Have a token.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,6 +1074,9 @@ LexNextToken:
|
||||||
// Done parsing the "line".
|
// Done parsing the "line".
|
||||||
ParsingPreprocessorDirective = false;
|
ParsingPreprocessorDirective = false;
|
||||||
|
|
||||||
|
// Restore comment saving mode, in case it was disabled for directive.
|
||||||
|
KeepCommentMode = Features.KeepComments;
|
||||||
|
|
||||||
// Since we consumed a newline, we are back at the start of a line.
|
// Since we consumed a newline, we are back at the start of a line.
|
||||||
IsAtStartOfLine = true;
|
IsAtStartOfLine = true;
|
||||||
|
|
||||||
|
@ -1211,13 +1253,13 @@ LexNextToken:
|
||||||
// 6.4.9: Comments
|
// 6.4.9: Comments
|
||||||
Char = getCharAndSize(CurPtr, SizeTmp);
|
Char = getCharAndSize(CurPtr, SizeTmp);
|
||||||
if (Char == '/') { // BCPL comment.
|
if (Char == '/') { // BCPL comment.
|
||||||
Result.SetFlag(LexerToken::LeadingSpace);
|
if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
|
||||||
SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result));
|
goto LexNextToken; // GCC isn't tail call eliminating.
|
||||||
goto LexNextToken; // GCC isn't tail call eliminating.
|
return; // KeepCommentMode
|
||||||
} else if (Char == '*') { // /**/ comment.
|
} else if (Char == '*') { // /**/ comment.
|
||||||
Result.SetFlag(LexerToken::LeadingSpace);
|
if (SkipBlockComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
|
||||||
SkipBlockComment(Result, ConsumeChar(CurPtr, SizeTmp, Result));
|
goto LexNextToken; // GCC isn't tail call eliminating.
|
||||||
goto LexNextToken; // GCC isn't tail call eliminating.
|
return; // KeepCommentMode
|
||||||
} else if (Char == '=') {
|
} else if (Char == '=') {
|
||||||
Result.SetKind(tok::slashequal);
|
Result.SetKind(tok::slashequal);
|
||||||
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
|
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
|
||||||
|
|
|
@ -755,6 +755,10 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(LexerToken &MacroName,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Otherwise, continue to add the tokens to this variable argument.
|
// Otherwise, continue to add the tokens to this variable argument.
|
||||||
|
} else if (Tok.getKind() == tok::comment && !Features.KeepMacroComments) {
|
||||||
|
// If this is a comment token in the argument list and we're just in
|
||||||
|
// -C mode (not -CC mode), discard the comment.
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgTokens.push_back(Tok);
|
ArgTokens.push_back(Tok);
|
||||||
|
@ -1221,6 +1225,8 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
|
||||||
// directive mode. Tell the lexer this so any newlines we see will be
|
// directive mode. Tell the lexer this so any newlines we see will be
|
||||||
// converted into an EOM token (this terminates the macro).
|
// converted into an EOM token (this terminates the macro).
|
||||||
CurLexer->ParsingPreprocessorDirective = true;
|
CurLexer->ParsingPreprocessorDirective = true;
|
||||||
|
CurLexer->KeepCommentMode = false;
|
||||||
|
|
||||||
|
|
||||||
// Read the next token, the directive flavor.
|
// Read the next token, the directive flavor.
|
||||||
LexUnexpandedToken(Tok);
|
LexUnexpandedToken(Tok);
|
||||||
|
@ -1229,6 +1235,8 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
|
||||||
// something bogus), skip it.
|
// something bogus), skip it.
|
||||||
if (Tok.getKind() != tok::identifier) {
|
if (Tok.getKind() != tok::identifier) {
|
||||||
CurLexer->ParsingPreprocessorDirective = false;
|
CurLexer->ParsingPreprocessorDirective = false;
|
||||||
|
// Restore comment saving mode.
|
||||||
|
CurLexer->KeepCommentMode = Features.KeepComments;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1242,6 +1250,8 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
|
||||||
if (FirstChar >= 'a' && FirstChar <= 'z' &&
|
if (FirstChar >= 'a' && FirstChar <= 'z' &&
|
||||||
FirstChar != 'i' && FirstChar != 'e') {
|
FirstChar != 'i' && FirstChar != 'e') {
|
||||||
CurLexer->ParsingPreprocessorDirective = false;
|
CurLexer->ParsingPreprocessorDirective = false;
|
||||||
|
// Restore comment saving mode.
|
||||||
|
CurLexer->KeepCommentMode = Features.KeepComments;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1261,6 +1271,8 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
|
||||||
IdLen = DirectiveStr.size();
|
IdLen = DirectiveStr.size();
|
||||||
if (IdLen >= 20) {
|
if (IdLen >= 20) {
|
||||||
CurLexer->ParsingPreprocessorDirective = false;
|
CurLexer->ParsingPreprocessorDirective = false;
|
||||||
|
// Restore comment saving mode.
|
||||||
|
CurLexer->KeepCommentMode = Features.KeepComments;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
memcpy(Directive, &DirectiveStr[0], IdLen);
|
memcpy(Directive, &DirectiveStr[0], IdLen);
|
||||||
|
@ -1339,6 +1351,8 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
CurLexer->ParsingPreprocessorDirective = false;
|
CurLexer->ParsingPreprocessorDirective = false;
|
||||||
|
// Restore comment saving mode.
|
||||||
|
CurLexer->KeepCommentMode = Features.KeepComments;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, if we are out of the conditional (saw an #endif or ran off the end
|
// Finally, if we are out of the conditional (saw an #endif or ran off the end
|
||||||
|
@ -1698,6 +1712,10 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok) {
|
||||||
if (MacroNameTok.getKind() == tok::eom)
|
if (MacroNameTok.getKind() == tok::eom)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// If we are supposed to keep comments in #defines, reenable comment saving
|
||||||
|
// mode.
|
||||||
|
CurLexer->KeepCommentMode = Features.KeepMacroComments;
|
||||||
|
|
||||||
MacroInfo *MI = new MacroInfo(MacroNameTok.getLocation());
|
MacroInfo *MI = new MacroInfo(MacroNameTok.getLocation());
|
||||||
|
|
||||||
LexerToken Tok;
|
LexerToken Tok;
|
||||||
|
|
|
@ -67,7 +67,6 @@ Lexer:
|
||||||
Preprocessor:
|
Preprocessor:
|
||||||
* #assert/#unassert
|
* #assert/#unassert
|
||||||
* #line / #file directives
|
* #line / #file directives
|
||||||
* -C output mode in -E mode.
|
|
||||||
* MSExtension: "L#param" stringizes to a wide string literal.
|
* MSExtension: "L#param" stringizes to a wide string literal.
|
||||||
|
|
||||||
Traditional Preprocessor:
|
Traditional Preprocessor:
|
||||||
|
|
|
@ -28,6 +28,9 @@ TOK(unknown) // Not a token.
|
||||||
TOK(eof) // End of file.
|
TOK(eof) // End of file.
|
||||||
TOK(eom) // End of macro (end of line inside a macro).
|
TOK(eom) // End of macro (end of line inside a macro).
|
||||||
|
|
||||||
|
// C99 6.4.9: Comments.
|
||||||
|
TOK(comment) // Comment (only in -E -C[C] mode)
|
||||||
|
|
||||||
// C99 6.4.2: Identifiers.
|
// C99 6.4.2: Identifiers.
|
||||||
TOK(identifier) // abcde123
|
TOK(identifier) // abcde123
|
||||||
|
|
||||||
|
|
|
@ -26,23 +26,27 @@ class Preprocessor;
|
||||||
class SourceBuffer;
|
class SourceBuffer;
|
||||||
|
|
||||||
struct LangOptions {
|
struct LangOptions {
|
||||||
unsigned Trigraphs : 1; // Trigraphs in source files.
|
unsigned Trigraphs : 1; // Trigraphs in source files.
|
||||||
unsigned BCPLComment : 1; // BCPL-style // comments.
|
unsigned BCPLComment : 1; // BCPL-style // comments.
|
||||||
unsigned DollarIdents : 1; // '$' allowed in identifiers.
|
unsigned DollarIdents : 1; // '$' allowed in identifiers.
|
||||||
unsigned Digraphs : 1; // When added to C? C99?
|
unsigned Digraphs : 1; // When added to C? C99?
|
||||||
unsigned HexFloats : 1; // C99 Hexadecimal float constants.
|
unsigned HexFloats : 1; // C99 Hexadecimal float constants.
|
||||||
unsigned C99 : 1; // C99 Support
|
unsigned C99 : 1; // C99 Support
|
||||||
unsigned Microsoft : 1; // Microsoft extensions.
|
unsigned Microsoft : 1; // Microsoft extensions.
|
||||||
unsigned CPlusPlus : 1; // C++ Support
|
unsigned CPlusPlus : 1; // C++ Support
|
||||||
unsigned CPPMinMax : 1; // C++ <?=, >?= tokens.
|
unsigned CPPMinMax : 1; // C++ <?=, >?= tokens.
|
||||||
unsigned NoExtensions : 1; // All extensions are disabled, strict mode.
|
unsigned NoExtensions : 1; // All extensions are disabled, strict mode.
|
||||||
|
|
||||||
unsigned ObjC1 : 1; // Objective C 1 support enabled.
|
unsigned ObjC1 : 1; // Objective C 1 support enabled.
|
||||||
unsigned ObjC2 : 1; // Objective C 2 support enabled (implies ObjC1).
|
unsigned ObjC2 : 1; // Objective C 2 support enabled.
|
||||||
|
|
||||||
|
unsigned KeepComments : 1; // Keep comments ("-C") mode.
|
||||||
|
unsigned KeepMacroComments : 1; // Keep macro-exp comments ("-CC") mode.
|
||||||
|
|
||||||
LangOptions() {
|
LangOptions() {
|
||||||
Trigraphs = BCPLComment = DollarIdents = Digraphs = ObjC1 = ObjC2 = 0;
|
Trigraphs = BCPLComment = DollarIdents = Digraphs = ObjC1 = ObjC2 = 0;
|
||||||
C99 = Microsoft = CPlusPlus = CPPMinMax = NoExtensions = 0;
|
C99 = Microsoft = CPlusPlus = CPPMinMax = NoExtensions = 0;
|
||||||
|
KeepComments = KeepMacroComments = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,6 +91,10 @@ class Lexer {
|
||||||
/// on an unterminated '/*' comment.
|
/// on an unterminated '/*' comment.
|
||||||
bool LexingRawMode;
|
bool LexingRawMode;
|
||||||
|
|
||||||
|
/// KeepCommentMode - The lexer can optionally keep C & BCPL-style comments,
|
||||||
|
/// and return them as tokens. This is used for -C and -CC modes.
|
||||||
|
bool KeepCommentMode;
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Context that changes as the file is lexed.
|
// Context that changes as the file is lexed.
|
||||||
// NOTE: any state that mutates when in raw mode must have save/restore code
|
// NOTE: any state that mutates when in raw mode must have save/restore code
|
||||||
|
@ -353,9 +361,9 @@ private:
|
||||||
bool LexEndOfFile (LexerToken &Result, const char *CurPtr);
|
bool LexEndOfFile (LexerToken &Result, const char *CurPtr);
|
||||||
|
|
||||||
void SkipWhitespace (LexerToken &Result, const char *CurPtr);
|
void SkipWhitespace (LexerToken &Result, const char *CurPtr);
|
||||||
void SkipBCPLComment (LexerToken &Result, const char *CurPtr);
|
bool SkipBCPLComment (LexerToken &Result, const char *CurPtr);
|
||||||
void SkipBlockComment (LexerToken &Result, const char *CurPtr);
|
bool SkipBlockComment (LexerToken &Result, const char *CurPtr);
|
||||||
|
bool SaveBCPLComment (LexerToken &Result, const char *CurPtr);
|
||||||
|
|
||||||
/// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
|
/// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
|
||||||
/// (potentially) macro expand the filename. If the sequence parsed is not
|
/// (potentially) macro expand the filename. If the sequence parsed is not
|
||||||
|
|
Loading…
Reference in New Issue