From: Chris Lattner Date: Fri, 26 Sep 2008 20:12:23 +0000 (+0000) Subject: Fix the rest of rdar://6243860 hopefully. This requires changing FileIDInfo X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=721818304ac462d8c6ce05eecd02884033db78f1;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56688 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 770ac803ae..c8a0b490d7 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -112,10 +112,11 @@ namespace SrcMgr { /// ChunkNo - Really large buffers are broken up into chunks that are /// each (1 << SourceLocation::FilePosBits) in size. This specifies the /// chunk number of this FileID. - unsigned ChunkNo:30; + unsigned ChunkNo : 30; - /// isSystemHeader - Set for system header files. - bool isSysHeader:1; + /// DirCharacteristic - This is an instance of DirectoryLookup::DirType, + /// indicating whether this is a system header dir or not. + unsigned DirCharacteristic : 2; /// Content - Information about the source buffer itself. const ContentCache* Content; @@ -123,19 +124,22 @@ namespace SrcMgr { public: /// get - Return a FileIDInfo object. static FileIDInfo get(SourceLocation IL, unsigned CN, - const ContentCache *Con, bool SysHeader) { + const ContentCache *Con, unsigned DirCharacter) { FileIDInfo X; X.IncludeLoc = IL; X.ChunkNo = CN; X.Content = Con; - X.isSysHeader = SysHeader; + X.DirCharacteristic = DirCharacter; return X; } SourceLocation getIncludeLoc() const { return IncludeLoc; } unsigned getChunkNo() const { return ChunkNo; } 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. void Emit(llvm::Serializer& S) const; @@ -250,10 +254,10 @@ public: /// being #included from the specified IncludePosition. This returns 0 on /// error and translates NULL into standard input. unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, - bool isSysHeader = false) { + unsigned DirCharacter) { const SrcMgr::ContentCache *IR = getContentCache(SourceFile); 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. @@ -261,17 +265,17 @@ public: SourceLocation IncludePos) { assert (MainFileID == 0 && "MainFileID already set!"); - MainFileID = createFileID(SourceFile,IncludePos); + MainFileID = createFileID(SourceFile, IncludePos, 0); return MainFileID; } /// createFileIDForMemBuffer - Create a new FileID that represents the /// specified memory buffer. This does no caching of the buffer and takes /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once. - unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer, - bool isSysHeader = false) { + unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { return createFileID(createMemBufferContentCache(Buffer), SourceLocation(), - isSysHeader); + // FIXME: USE ENUM + 0/*normal header*/); } /// createMainFileIDForMembuffer - Create the FileID for a memory buffer @@ -432,8 +436,13 @@ public: /// isInSystemHeader - Returns if a SourceLocation is in a system header. 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. /// @@ -453,7 +462,7 @@ private: /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. 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 /// file. This returns null on failure. diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index cc056ead5d..96a4153acf 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -458,9 +458,6 @@ private: /// #include. 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 /// current line until the tok::eom token is found. void DiscardUntilEndOfDirective(); diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 7534ac4f26..66a85146a1 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -76,14 +76,14 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { /// corresponds to a file or some other input source. unsigned SourceManager::createFileID(const ContentCache *File, SourceLocation IncludePos, - bool isSysHeader) { + unsigned DirCharacter) { // 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 // this, we create one FileID for each chunk of the file that fits in a // FilePos field. unsigned FileSize = File->Buffer->getBufferSize(); 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) && "Ran out of file ID's!"); return FileIDs.size(); @@ -95,7 +95,7 @@ unsigned SourceManager::createFileID(const ContentCache *File, unsigned ChunkNo = 0; while (1) { FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File, - isSysHeader)); + DirCharacter)); if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break; FileSize -= (1 << SourceLocation::FilePosBits); diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 70cd0ed1d0..504bc45dca 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -600,7 +600,8 @@ static bool ConcatenateIncludeName(llvm::SmallVector &FilenameBuffer, /// HandleIncludeDirective - The "#include" tokens have just been read, read the /// file to be included from the lexer, then include it! This is a common /// 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, const DirectoryLookup *LookupFrom, bool isImport) { @@ -666,15 +667,22 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok, return Diag(FilenameTok, diag::err_pp_file_not_found, std::string(FilenameStart, FilenameEnd)); - // Ask HeaderInfo if we should enter this #include file. - if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) { - // If it returns true, #including this file will have no effect. + // Ask HeaderInfo if we should enter this #include file. If not, #including + // this file will have no effect. + if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) 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. unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(), - isSystemHeader(File)); + FileCharacter); if (FileID == 0) return Diag(FilenameTok, diag::err_pp_file_not_found, std::string(FilenameStart, FilenameEnd)); diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index d1c44cfcdf..1522bf5e8c 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -78,7 +78,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID, Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this); EnterSourceFileWithLexer(TheLexer, CurDir); } - + /// EnterSourceFile - Add a source file to the top of the include stack and /// start lexing tokens from it instead of the current buffer. 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. if (Callbacks && !CurLexer->Is_PragmaLexer) { - DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir; - - // Get the file entry for the current file. - if (const FileEntry *FE = - SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc())) - FileType = HeaderInfo.getFileDirFlavor(FE); + DirectoryLookup::DirType FileType = + // FIXME: + (DirectoryLookup::DirType) + SourceMgr.getDirCharacteristic(CurLexer->getFileLoc()); Callbacks->FileChanged(CurLexer->getFileLoc(), 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. 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), PPCallbacks::ExitFile, FileType); } diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 36e80c91cf..691f46ac2d 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -117,17 +117,6 @@ Preprocessor::~Preprocessor() { 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 /// the specified Token's location, translating the token's start /// position in the current buffer into a SourcePosition object for rendering.