Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
cfe/trunk/lib/Lex/PPLexerChange.cpp
//===--- PPLexerChange.cpp - Handle changing lexers in the preprocessor ---===// | //===--- PPLexerChange.cpp - Handle changing lexers in the preprocessor ---===// | ||||
// | // | ||||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | ||||
// | // | ||||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | ||||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// | // | ||||
// This file implements pieces of the Preprocessor interface that manage the | // This file implements pieces of the Preprocessor interface that manage the | ||||
// current lexer stack. | // current lexer stack. | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "clang/Lex/Preprocessor.h" | #include "clang/Lex/Preprocessor.h" | ||||
#include "clang/Lex/PreprocessorOptions.h" | |||||
#include "clang/Basic/FileManager.h" | #include "clang/Basic/FileManager.h" | ||||
#include "clang/Basic/SourceManager.h" | #include "clang/Basic/SourceManager.h" | ||||
#include "clang/Lex/HeaderSearch.h" | #include "clang/Lex/HeaderSearch.h" | ||||
#include "clang/Lex/LexDiagnostic.h" | #include "clang/Lex/LexDiagnostic.h" | ||||
#include "clang/Lex/MacroInfo.h" | #include "clang/Lex/MacroInfo.h" | ||||
#include "clang/Lex/PTHManager.h" | #include "clang/Lex/PTHManager.h" | ||||
#include "llvm/ADT/StringSwitch.h" | #include "llvm/ADT/StringSwitch.h" | ||||
#include "llvm/Support/FileSystem.h" | #include "llvm/Support/FileSystem.h" | ||||
▲ Show 20 Lines • Show All 396 Lines • ▼ Show 20 Lines | bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { | ||||
if (PragmaAssumeNonNullLoc.isValid() && | if (PragmaAssumeNonNullLoc.isValid() && | ||||
!isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) { | !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) { | ||||
Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull); | Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull); | ||||
// Recover by leaving immediately. | // Recover by leaving immediately. | ||||
PragmaAssumeNonNullLoc = SourceLocation(); | PragmaAssumeNonNullLoc = SourceLocation(); | ||||
} | } | ||||
bool LeavingPCHThroughHeader = false; | |||||
// If this is a #include'd file, pop it off the include stack and continue | // If this is a #include'd file, pop it off the include stack and continue | ||||
// lexing the #includer file. | // lexing the #includer file. | ||||
if (!IncludeMacroStack.empty()) { | if (!IncludeMacroStack.empty()) { | ||||
// If we lexed the code-completion file, act as if we reached EOF. | // If we lexed the code-completion file, act as if we reached EOF. | ||||
if (isCodeCompletionEnabled() && CurPPLexer && | if (isCodeCompletionEnabled() && CurPPLexer && | ||||
SourceMgr.getLocForStartOfFile(CurPPLexer->getFileID()) == | SourceMgr.getLocForStartOfFile(CurPPLexer->getFileID()) == | ||||
CodeCompletionFileLoc) { | CodeCompletionFileLoc) { | ||||
Show All 40 Lines | if (LeavingSubmodule) { | ||||
const char *EndPos = getCurLexerEndPos(); | const char *EndPos = getCurLexerEndPos(); | ||||
Result.startToken(); | Result.startToken(); | ||||
CurLexer->BufferPtr = EndPos; | CurLexer->BufferPtr = EndPos; | ||||
CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); | CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); | ||||
Result.setAnnotationEndLoc(Result.getLocation()); | Result.setAnnotationEndLoc(Result.getLocation()); | ||||
Result.setAnnotationValue(M); | Result.setAnnotationValue(M); | ||||
} | } | ||||
bool FoundPCHThroughHeader = false; | |||||
if (CurPPLexer && creatingPCHWithThroughHeader() && | |||||
isPCHThroughHeader( | |||||
SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))) | |||||
FoundPCHThroughHeader = true; | |||||
// We're done with the #included file. | // We're done with the #included file. | ||||
RemoveTopOfLexerStack(); | RemoveTopOfLexerStack(); | ||||
// Propagate info about start-of-line/leading white-space/etc. | // Propagate info about start-of-line/leading white-space/etc. | ||||
PropagateLineStartLeadingSpaceInfo(Result); | PropagateLineStartLeadingSpaceInfo(Result); | ||||
// Notify the client, if desired, that we are in a new source file. | // Notify the client, if desired, that we are in a new source file. | ||||
if (Callbacks && !isEndOfMacro && CurPPLexer) { | if (Callbacks && !isEndOfMacro && CurPPLexer) { | ||||
SrcMgr::CharacteristicKind FileType = | SrcMgr::CharacteristicKind FileType = | ||||
SourceMgr.getFileCharacteristic(CurPPLexer->getSourceLocation()); | SourceMgr.getFileCharacteristic(CurPPLexer->getSourceLocation()); | ||||
Callbacks->FileChanged(CurPPLexer->getSourceLocation(), | Callbacks->FileChanged(CurPPLexer->getSourceLocation(), | ||||
PPCallbacks::ExitFile, FileType, ExitedFID); | PPCallbacks::ExitFile, FileType, ExitedFID); | ||||
} | } | ||||
// Restore conditional stack from the preamble right after exiting from the | // Restore conditional stack from the preamble right after exiting from the | ||||
// predefines file. | // predefines file. | ||||
if (ExitedFromPredefinesFile) | if (ExitedFromPredefinesFile) | ||||
replayPreambleConditionalStack(); | replayPreambleConditionalStack(); | ||||
if (!isEndOfMacro && CurPPLexer && FoundPCHThroughHeader && | |||||
(isInPrimaryFile() || | |||||
CurPPLexer->getFileID() == getPredefinesFileID())) { | |||||
// Leaving the through header. Continue directly to end of main file | |||||
// processing. | |||||
LeavingPCHThroughHeader = true; | |||||
} else { | |||||
// Client should lex another token unless we generated an EOM. | // Client should lex another token unless we generated an EOM. | ||||
return LeavingSubmodule; | return LeavingSubmodule; | ||||
} | } | ||||
} | |||||
// If this is the end of the main file, form an EOF token. | // If this is the end of the main file, form an EOF token. | ||||
if (CurLexer) { | if (CurLexer) { | ||||
const char *EndPos = getCurLexerEndPos(); | const char *EndPos = getCurLexerEndPos(); | ||||
Result.startToken(); | Result.startToken(); | ||||
CurLexer->BufferPtr = EndPos; | CurLexer->BufferPtr = EndPos; | ||||
CurLexer->FormTokenWithChars(Result, EndPos, tok::eof); | CurLexer->FormTokenWithChars(Result, EndPos, tok::eof); | ||||
if (isCodeCompletionEnabled()) { | if (isCodeCompletionEnabled()) { | ||||
// Inserting the code-completion point increases the source buffer by 1, | // Inserting the code-completion point increases the source buffer by 1, | ||||
// but the main FileID was created before inserting the point. | // but the main FileID was created before inserting the point. | ||||
// Compensate by reducing the EOF location by 1, otherwise the location | // Compensate by reducing the EOF location by 1, otherwise the location | ||||
// will point to the next FileID. | // will point to the next FileID. | ||||
// FIXME: This is hacky, the code-completion point should probably be | // FIXME: This is hacky, the code-completion point should probably be | ||||
// inserted before the main FileID is created. | // inserted before the main FileID is created. | ||||
if (CurLexer->getFileLoc() == CodeCompletionFileLoc) | if (CurLexer->getFileLoc() == CodeCompletionFileLoc) | ||||
Result.setLocation(Result.getLocation().getLocWithOffset(-1)); | Result.setLocation(Result.getLocation().getLocWithOffset(-1)); | ||||
} | } | ||||
if (creatingPCHWithThroughHeader() && !LeavingPCHThroughHeader) { | |||||
// Reached the end of the compilation without finding the through header. | |||||
Diag(CurLexer->getFileLoc(), diag::err_pp_through_header_not_seen) | |||||
<< PPOpts->PCHThroughHeader << 0; | |||||
} | |||||
if (!isIncrementalProcessingEnabled()) | if (!isIncrementalProcessingEnabled()) | ||||
// We're done with lexing. | // We're done with lexing. | ||||
CurLexer.reset(); | CurLexer.reset(); | ||||
} else { | } else { | ||||
assert(CurPTHLexer && "Got EOF but no current lexer set!"); | assert(CurPTHLexer && "Got EOF but no current lexer set!"); | ||||
CurPTHLexer->getEOF(Result); | CurPTHLexer->getEOF(Result); | ||||
CurPTHLexer.reset(); | CurPTHLexer.reset(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 307 Lines • Show Last 20 Lines |