Fix the rest of rdar://6243860 hopefully. This requires changing FileIDInfo
to whether the fileid is a 'extern c system header' in addition to whether it is a system header, most of this is spreading plumbing around. Once we have that, PPLexerChange bases its "file enter/exit" notifications to PPCallbacks to base the system header state on FileIDInfo instead of HeaderSearch. Finally, in Preprocessor::HandleIncludeDirective, mirror logic in GCC: the system headerness of a file being entered can be set due to the #includer or the #includee. llvm-svn: 56688
This commit is contained in:
parent
71efd8159e
commit
c88a23e8d7
|
@ -112,10 +112,11 @@ namespace SrcMgr {
|
||||||
/// ChunkNo - Really large buffers are broken up into chunks that are
|
/// ChunkNo - Really large buffers are broken up into chunks that are
|
||||||
/// each (1 << SourceLocation::FilePosBits) in size. This specifies the
|
/// each (1 << SourceLocation::FilePosBits) in size. This specifies the
|
||||||
/// chunk number of this FileID.
|
/// chunk number of this FileID.
|
||||||
unsigned ChunkNo:30;
|
unsigned ChunkNo : 30;
|
||||||
|
|
||||||
/// isSystemHeader - Set for system header files.
|
/// DirCharacteristic - This is an instance of DirectoryLookup::DirType,
|
||||||
bool isSysHeader:1;
|
/// indicating whether this is a system header dir or not.
|
||||||
|
unsigned DirCharacteristic : 2;
|
||||||
|
|
||||||
/// Content - Information about the source buffer itself.
|
/// Content - Information about the source buffer itself.
|
||||||
const ContentCache* Content;
|
const ContentCache* Content;
|
||||||
|
@ -123,19 +124,22 @@ namespace SrcMgr {
|
||||||
public:
|
public:
|
||||||
/// get - Return a FileIDInfo object.
|
/// get - Return a FileIDInfo object.
|
||||||
static FileIDInfo get(SourceLocation IL, unsigned CN,
|
static FileIDInfo get(SourceLocation IL, unsigned CN,
|
||||||
const ContentCache *Con, bool SysHeader) {
|
const ContentCache *Con, unsigned DirCharacter) {
|
||||||
FileIDInfo X;
|
FileIDInfo X;
|
||||||
X.IncludeLoc = IL;
|
X.IncludeLoc = IL;
|
||||||
X.ChunkNo = CN;
|
X.ChunkNo = CN;
|
||||||
X.Content = Con;
|
X.Content = Con;
|
||||||
X.isSysHeader = SysHeader;
|
X.DirCharacteristic = DirCharacter;
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLocation getIncludeLoc() const { return IncludeLoc; }
|
SourceLocation getIncludeLoc() const { return IncludeLoc; }
|
||||||
unsigned getChunkNo() const { return ChunkNo; }
|
unsigned getChunkNo() const { return ChunkNo; }
|
||||||
const ContentCache* getContentCache() const { return Content; }
|
const ContentCache* getContentCache() const { return Content; }
|
||||||
bool isSystemHeader() const { return isSysHeader; }
|
|
||||||
|
/// getDirCharacteristic - Return whether this is a system header or not.
|
||||||
|
/// FIXME: rename from dir to file?
|
||||||
|
unsigned getDirCharacteristic() const { return DirCharacteristic; }
|
||||||
|
|
||||||
/// Emit - Emit this FileIDInfo to Bitcode.
|
/// Emit - Emit this FileIDInfo to Bitcode.
|
||||||
void Emit(llvm::Serializer& S) const;
|
void Emit(llvm::Serializer& S) const;
|
||||||
|
@ -250,10 +254,10 @@ public:
|
||||||
/// being #included from the specified IncludePosition. This returns 0 on
|
/// being #included from the specified IncludePosition. This returns 0 on
|
||||||
/// error and translates NULL into standard input.
|
/// error and translates NULL into standard input.
|
||||||
unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
|
unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
|
||||||
bool isSysHeader = false) {
|
unsigned DirCharacter) {
|
||||||
const SrcMgr::ContentCache *IR = getContentCache(SourceFile);
|
const SrcMgr::ContentCache *IR = getContentCache(SourceFile);
|
||||||
if (IR == 0) return 0; // Error opening file?
|
if (IR == 0) return 0; // Error opening file?
|
||||||
return createFileID(IR, IncludePos, isSysHeader);
|
return createFileID(IR, IncludePos, DirCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createMainFileID - Create the FileID for the main source file.
|
/// createMainFileID - Create the FileID for the main source file.
|
||||||
|
@ -261,17 +265,17 @@ public:
|
||||||
SourceLocation IncludePos) {
|
SourceLocation IncludePos) {
|
||||||
|
|
||||||
assert (MainFileID == 0 && "MainFileID already set!");
|
assert (MainFileID == 0 && "MainFileID already set!");
|
||||||
MainFileID = createFileID(SourceFile,IncludePos);
|
MainFileID = createFileID(SourceFile, IncludePos, 0);
|
||||||
return MainFileID;
|
return MainFileID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createFileIDForMemBuffer - Create a new FileID that represents the
|
/// createFileIDForMemBuffer - Create a new FileID that represents the
|
||||||
/// specified memory buffer. This does no caching of the buffer and takes
|
/// specified memory buffer. This does no caching of the buffer and takes
|
||||||
/// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
|
/// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
|
||||||
unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
|
unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
|
||||||
bool isSysHeader = false) {
|
|
||||||
return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
|
return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
|
||||||
isSysHeader);
|
// FIXME: USE ENUM
|
||||||
|
0/*normal header*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createMainFileIDForMembuffer - Create the FileID for a memory buffer
|
/// createMainFileIDForMembuffer - Create the FileID for a memory buffer
|
||||||
|
@ -432,8 +436,13 @@ public:
|
||||||
|
|
||||||
/// isInSystemHeader - Returns if a SourceLocation is in a system header.
|
/// isInSystemHeader - Returns if a SourceLocation is in a system header.
|
||||||
bool isInSystemHeader(SourceLocation Loc) const {
|
bool isInSystemHeader(SourceLocation Loc) const {
|
||||||
return getFIDInfo(getPhysicalLoc(Loc).getFileID())->isSystemHeader();
|
// FIXME: Use proper enum here!
|
||||||
|
return getDirCharacteristic(Loc) != 0;
|
||||||
}
|
}
|
||||||
|
unsigned getDirCharacteristic(SourceLocation Loc) const {
|
||||||
|
return getFIDInfo(getPhysicalLoc(Loc).getFileID())->getDirCharacteristic();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// PrintStats - Print statistics to stderr.
|
/// PrintStats - Print statistics to stderr.
|
||||||
///
|
///
|
||||||
|
@ -453,7 +462,7 @@ private:
|
||||||
/// include position. This works regardless of whether the ContentCache
|
/// include position. This works regardless of whether the ContentCache
|
||||||
/// corresponds to a file or some other input source.
|
/// corresponds to a file or some other input source.
|
||||||
unsigned createFileID(const SrcMgr::ContentCache* File,
|
unsigned createFileID(const SrcMgr::ContentCache* File,
|
||||||
SourceLocation IncludePos, bool isSysHeader = false);
|
SourceLocation IncludePos, unsigned DirCharacter);
|
||||||
|
|
||||||
/// getContentCache - Create or return a cached ContentCache for the specified
|
/// getContentCache - Create or return a cached ContentCache for the specified
|
||||||
/// file. This returns null on failure.
|
/// file. This returns null on failure.
|
||||||
|
|
|
@ -458,9 +458,6 @@ private:
|
||||||
/// #include.
|
/// #include.
|
||||||
bool isInPrimaryFile() const;
|
bool isInPrimaryFile() const;
|
||||||
|
|
||||||
/// isSystemHeader - Return true if F is a system header.
|
|
||||||
bool isSystemHeader(const FileEntry* F) const;
|
|
||||||
|
|
||||||
/// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
|
/// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
|
||||||
/// current line until the tok::eom token is found.
|
/// current line until the tok::eom token is found.
|
||||||
void DiscardUntilEndOfDirective();
|
void DiscardUntilEndOfDirective();
|
||||||
|
|
|
@ -76,14 +76,14 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
|
||||||
/// corresponds to a file or some other input source.
|
/// corresponds to a file or some other input source.
|
||||||
unsigned SourceManager::createFileID(const ContentCache *File,
|
unsigned SourceManager::createFileID(const ContentCache *File,
|
||||||
SourceLocation IncludePos,
|
SourceLocation IncludePos,
|
||||||
bool isSysHeader) {
|
unsigned DirCharacter) {
|
||||||
// If FileEnt is really large (e.g. it's a large .i file), we may not be able
|
// If FileEnt is really large (e.g. it's a large .i file), we may not be able
|
||||||
// to fit an arbitrary position in the file in the FilePos field. To handle
|
// to fit an arbitrary position in the file in the FilePos field. To handle
|
||||||
// this, we create one FileID for each chunk of the file that fits in a
|
// this, we create one FileID for each chunk of the file that fits in a
|
||||||
// FilePos field.
|
// FilePos field.
|
||||||
unsigned FileSize = File->Buffer->getBufferSize();
|
unsigned FileSize = File->Buffer->getBufferSize();
|
||||||
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
|
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
|
||||||
FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, isSysHeader));
|
FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, DirCharacter));
|
||||||
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
|
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
|
||||||
"Ran out of file ID's!");
|
"Ran out of file ID's!");
|
||||||
return FileIDs.size();
|
return FileIDs.size();
|
||||||
|
@ -95,7 +95,7 @@ unsigned SourceManager::createFileID(const ContentCache *File,
|
||||||
unsigned ChunkNo = 0;
|
unsigned ChunkNo = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File,
|
FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File,
|
||||||
isSysHeader));
|
DirCharacter));
|
||||||
|
|
||||||
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
|
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
|
||||||
FileSize -= (1 << SourceLocation::FilePosBits);
|
FileSize -= (1 << SourceLocation::FilePosBits);
|
||||||
|
|
|
@ -600,7 +600,8 @@ static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
|
||||||
/// HandleIncludeDirective - The "#include" tokens have just been read, read the
|
/// HandleIncludeDirective - The "#include" tokens have just been read, read the
|
||||||
/// file to be included from the lexer, then include it! This is a common
|
/// file to be included from the lexer, then include it! This is a common
|
||||||
/// routine with functionality shared between #include, #include_next and
|
/// routine with functionality shared between #include, #include_next and
|
||||||
/// #import.
|
/// #import. LookupFrom is set when this is a #include_next directive, it
|
||||||
|
/// specifies the file to start searching from.
|
||||||
void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
|
void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
|
||||||
const DirectoryLookup *LookupFrom,
|
const DirectoryLookup *LookupFrom,
|
||||||
bool isImport) {
|
bool isImport) {
|
||||||
|
@ -666,15 +667,22 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
|
||||||
return Diag(FilenameTok, diag::err_pp_file_not_found,
|
return Diag(FilenameTok, diag::err_pp_file_not_found,
|
||||||
std::string(FilenameStart, FilenameEnd));
|
std::string(FilenameStart, FilenameEnd));
|
||||||
|
|
||||||
// Ask HeaderInfo if we should enter this #include file.
|
// Ask HeaderInfo if we should enter this #include file. If not, #including
|
||||||
if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) {
|
// this file will have no effect.
|
||||||
// If it returns true, #including this file will have no effect.
|
if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
// The #included file will be considered to be a system header if either it is
|
||||||
|
// in a system include directory, or if the #includer is a system include
|
||||||
|
// header.
|
||||||
|
unsigned FileCharacter =
|
||||||
|
// FIXME: Casts
|
||||||
|
std::max((unsigned)HeaderInfo.getFileDirFlavor(File),
|
||||||
|
SourceMgr.getDirCharacteristic(getCurrentFileLexer()->getFileLoc()));
|
||||||
|
|
||||||
// Look up the file, create a File ID for it.
|
// Look up the file, create a File ID for it.
|
||||||
unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
|
unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
|
||||||
isSystemHeader(File));
|
FileCharacter);
|
||||||
if (FileID == 0)
|
if (FileID == 0)
|
||||||
return Diag(FilenameTok, diag::err_pp_file_not_found,
|
return Diag(FilenameTok, diag::err_pp_file_not_found,
|
||||||
std::string(FilenameStart, FilenameEnd));
|
std::string(FilenameStart, FilenameEnd));
|
||||||
|
|
|
@ -78,7 +78,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
|
||||||
Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this);
|
Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this);
|
||||||
EnterSourceFileWithLexer(TheLexer, CurDir);
|
EnterSourceFileWithLexer(TheLexer, CurDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EnterSourceFile - Add a source file to the top of the include stack and
|
/// EnterSourceFile - Add a source file 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 Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
|
void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
|
||||||
|
@ -95,12 +95,10 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
|
||||||
|
|
||||||
// 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 && !CurLexer->Is_PragmaLexer) {
|
if (Callbacks && !CurLexer->Is_PragmaLexer) {
|
||||||
DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
|
DirectoryLookup::DirType FileType =
|
||||||
|
// FIXME:
|
||||||
// Get the file entry for the current file.
|
(DirectoryLookup::DirType)
|
||||||
if (const FileEntry *FE =
|
SourceMgr.getDirCharacteristic(CurLexer->getFileLoc());
|
||||||
SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc()))
|
|
||||||
FileType = HeaderInfo.getFileDirFlavor(FE);
|
|
||||||
|
|
||||||
Callbacks->FileChanged(CurLexer->getFileLoc(),
|
Callbacks->FileChanged(CurLexer->getFileLoc(),
|
||||||
PPCallbacks::EnterFile, FileType);
|
PPCallbacks::EnterFile, FileType);
|
||||||
|
@ -182,13 +180,11 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
|
||||||
|
|
||||||
// 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 && CurLexer) {
|
if (Callbacks && !isEndOfMacro && CurLexer) {
|
||||||
DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
|
DirectoryLookup::DirType FileType =
|
||||||
|
// FIXME:
|
||||||
|
(DirectoryLookup::DirType)
|
||||||
|
SourceMgr.getDirCharacteristic(CurLexer->getFileLoc());
|
||||||
|
|
||||||
// Get the file entry for the current file.
|
|
||||||
if (const FileEntry *FE =
|
|
||||||
SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc()))
|
|
||||||
FileType = HeaderInfo.getFileDirFlavor(FE);
|
|
||||||
|
|
||||||
Callbacks->FileChanged(CurLexer->getSourceLocation(CurLexer->BufferPtr),
|
Callbacks->FileChanged(CurLexer->getSourceLocation(CurLexer->BufferPtr),
|
||||||
PPCallbacks::ExitFile, FileType);
|
PPCallbacks::ExitFile, FileType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,17 +117,6 @@ Preprocessor::~Preprocessor() {
|
||||||
delete Callbacks;
|
delete Callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Preprocessor::isSystemHeader(const FileEntry* F) const {
|
|
||||||
if (F) {
|
|
||||||
DirectoryLookup::DirType DirInfo = HeaderInfo.getFileDirFlavor(F);
|
|
||||||
if (DirInfo == DirectoryLookup::SystemHeaderDir ||
|
|
||||||
DirInfo == DirectoryLookup::ExternCSystemHeaderDir)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
|
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
|
||||||
/// the specified Token's location, translating the token's start
|
/// the specified Token's location, translating the token's start
|
||||||
/// position in the current buffer into a SourcePosition object for rendering.
|
/// position in the current buffer into a SourcePosition object for rendering.
|
||||||
|
|
Loading…
Reference in New Issue