diff options
author | Steve Naroff <snaroff@apple.com> | 2009-04-24 20:03:17 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-04-24 20:03:17 +0000 |
commit | 83d63c78810556d26b62ac4cbae2eda6cdd2570c (patch) | |
tree | 7444231d9436acad4d523469ba2b027355c4ad2f | |
parent | ff11cd148b66fb4dfb4eef5b9f8c711ab80bd634 (diff) |
Add PCH support for #import.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69987 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Frontend/PCHBitCodes.h | 6 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 64 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 19 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 18 | ||||
-rw-r--r-- | lib/Lex/HeaderSearch.cpp | 12 | ||||
-rw-r--r-- | lib/Lex/PPLexerChange.cpp | 2 | ||||
-rw-r--r-- | test/PCH/objc_import.h | 7 | ||||
-rw-r--r-- | test/PCH/objc_import.m | 15 |
8 files changed, 105 insertions, 38 deletions
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index c7c201ddd5..31a30b8f4d 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -211,7 +211,11 @@ namespace clang { /// \brief The value of the next __COUNTER__ to dispense. /// [PP_COUNTER_VALUE, Val] - PP_COUNTER_VALUE = 4 + PP_COUNTER_VALUE = 4, + + /// \brief Describes one header file info [isImport, DirInfo, NumIncludes] + /// ControlloingMacro is optional. + PP_HEADER_FILE_INFO = 5 }; /// \defgroup PCHAST Precompiled header AST constants diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index ef860c589e..fe7e7aef3b 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -23,7 +23,31 @@ class FileEntry; class FileManager; class IdentifierInfo; - +/// HeaderFileInfo - The preprocessor keeps track of this information for each +/// file that is #included. +struct HeaderFileInfo { + /// isImport - True if this is a #import'd or #pragma once file. + bool isImport : 1; + + /// DirInfo - Keep track of whether this is a system header, and if so, + /// whether it is C++ clean or not. This can be set by the include paths or + /// by #pragma gcc system_header. This is an instance of + /// SrcMgr::CharacteristicKind. + unsigned DirInfo : 2; + + /// NumIncludes - This is the number of times the file has been included + /// already. + unsigned short NumIncludes; + + /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard + /// that protects the entire contents of the file, this is the identifier + /// for the macro that controls whether or not it has any effect. + const IdentifierInfo *ControllingMacro; + + HeaderFileInfo() : isImport(false), DirInfo(SrcMgr::C_User), + NumIncludes(0), ControllingMacro(0) {} +}; + /// HeaderSearch - This class encapsulates the information needed to find the /// file referenced by a #include or #include_next, (sub-)framework lookup, etc. class HeaderSearch { @@ -39,35 +63,10 @@ class HeaderSearch { unsigned SystemDirIdx; bool NoCurDirSearch; - /// PreFileInfo - The preprocessor keeps track of this information for each - /// file that is #included. - struct PerFileInfo { - /// isImport - True if this is a #import'd or #pragma once file. - bool isImport : 1; - - /// DirInfo - Keep track of whether this is a system header, and if so, - /// whether it is C++ clean or not. This can be set by the include paths or - /// by #pragma gcc system_header. This is an instance of - /// SrcMgr::CharacteristicKind. - unsigned DirInfo : 2; - - /// NumIncludes - This is the number of times the file has been included - /// already. - unsigned short NumIncludes; - - /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard - /// that protects the entire contents of the file, this is the identifier - /// for the macro that controls whether or not it has any effect. - const IdentifierInfo *ControllingMacro; - - PerFileInfo() : isImport(false), DirInfo(SrcMgr::C_User), - NumIncludes(0), ControllingMacro(0) {} - }; - /// FileInfo - This contains all of the preprocessor-specific data about files /// that are included. The vector is indexed by the FileEntry's UID. /// - std::vector<PerFileInfo> FileInfo; + std::vector<HeaderFileInfo> FileInfo; /// LookupFileCache - This is keeps track of each lookup performed by /// LookupFile. The first part of the value is the starting index in @@ -190,13 +189,20 @@ public: const HeaderMap *CreateHeaderMap(const FileEntry *FE); void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } + + typedef std::vector<HeaderFileInfo>::iterator header_file_iterator; + header_file_iterator header_file_begin() { return FileInfo.begin(); } + header_file_iterator header_file_end() { return FileInfo.end(); } + + // Used by PCHReader. + void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID); void PrintStats(); private: - /// getFileInfo - Return the PerFileInfo structure for the specified + /// getFileInfo - Return the HeaderFileInfo structure for the specified /// FileEntry. - PerFileInfo &getFileInfo(const FileEntry *FE); + HeaderFileInfo &getFileInfo(const FileEntry *FE); }; } // end namespace clang diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index d97cf810ba..62d0ba4f9f 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -23,6 +23,7 @@ #include "clang/AST/Type.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/HeaderSearch.h" #include "clang/Basic/OnDiskHashTable.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" @@ -1444,6 +1445,7 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) { RecordData Record; llvm::SmallVector<IdentifierInfo*, 16> MacroArgs; MacroInfo *Macro = 0; + while (true) { unsigned Code = Stream.ReadCode(); switch (Code) { @@ -1536,7 +1538,9 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) { Macro->AddTokenToBody(Tok); break; } - } + case pch::PP_HEADER_FILE_INFO: + break; // Already processed by ReadPreprocessorBlock(). + } } } @@ -1545,6 +1549,7 @@ bool PCHReader::ReadPreprocessorBlock() { return Error("Malformed preprocessor block record"); RecordData Record; + unsigned NumHeaderInfos = 0; while (true) { unsigned Code = Stream.ReadCode(); switch (Code) { @@ -1581,8 +1586,16 @@ bool PCHReader::ReadPreprocessorBlock() { case pch::PP_MACRO_OBJECT_LIKE: case pch::PP_MACRO_FUNCTION_LIKE: case pch::PP_TOKEN: - // Once we've hit a macro definition or a token, we're done. - return false; + break; + case pch::PP_HEADER_FILE_INFO: { + HeaderFileInfo HFI; + HFI.isImport = Record[0]; + HFI.DirInfo = Record[1]; + HFI.NumIncludes = Record[2]; + HFI.ControllingMacro = DecodeIdentifierInfo(Record[3]); + PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++); + break; + } } } } diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 1af093a1cc..de4b9990b1 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -23,6 +23,7 @@ #include "clang/AST/Type.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/HeaderSearch.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/OnDiskHashTable.h" #include "clang/Basic/SourceManager.h" @@ -1547,7 +1548,22 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) { } ++NumMacros; } - + + // Loop over all the header files. + HeaderSearch &HS = PP.getHeaderSearchInfo(); + for (HeaderSearch::header_file_iterator I = HS.header_file_begin(), + E = HS.header_file_end(); + I != E; ++I) { + Record.push_back((*I).isImport); + Record.push_back((*I).DirInfo); + Record.push_back((*I).NumIncludes); + if ((*I).ControllingMacro) + AddIdentifierRef((*I).ControllingMacro, Record); + else + Record.push_back(0); + Stream.EmitRecord(pch::PP_HEADER_FILE_INFO, Record); + Record.clear(); + } Stream.ExitBlock(); } diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index 2cc29ecbed..ddea8e52a0 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -377,14 +377,20 @@ LookupSubframeworkHeader(const char *FilenameStart, //===----------------------------------------------------------------------===// -/// getFileInfo - Return the PerFileInfo structure for the specified +/// getFileInfo - Return the HeaderFileInfo structure for the specified /// FileEntry. -HeaderSearch::PerFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { +HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { if (FE->getUID() >= FileInfo.size()) FileInfo.resize(FE->getUID()+1); return FileInfo[FE->getUID()]; } +void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { + if (UID >= FileInfo.size()) + FileInfo.resize(UID+1); + FileInfo[UID] = HFI; +} + /// ShouldEnterIncludeFile - Mark the specified file as a target of of a /// #include, #include_next, or #import directive. Return false if #including /// the file will have no effect or true if we should include it. @@ -392,7 +398,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ ++NumIncluded; // Count # of attempted #includes. // Get information about this file. - PerFileInfo &FileInfo = getFileInfo(File); + HeaderFileInfo &FileInfo = getFileInfo(File); // If this is a #import directive, check that we have not already imported // this header. diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index 6f61c6516b..2a05ba336f 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -179,7 +179,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { if (CurPPLexer) { // Not ending a macro, ignore it. if (const IdentifierInfo *ControllingMacro = CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) { - // Okay, this has a controlling macro, remember in PerFileInfo. + // Okay, this has a controlling macro, remember in HeaderFileInfo. if (const FileEntry *FE = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) HeaderInfo.SetFileControllingMacro(FE, ControllingMacro); diff --git a/test/PCH/objc_import.h b/test/PCH/objc_import.h new file mode 100644 index 0000000000..8af87ab25c --- /dev/null +++ b/test/PCH/objc_import.h @@ -0,0 +1,7 @@ +/* For use with the objc_import.m test */ + +@interface TestPCH ++ alloc; +- (void)instMethod; +@end + diff --git a/test/PCH/objc_import.m b/test/PCH/objc_import.m new file mode 100644 index 0000000000..86c1c25ae5 --- /dev/null +++ b/test/PCH/objc_import.m @@ -0,0 +1,15 @@ +// Test this without pch. +// RUN: clang-cc -include %S/objc_import.h -fsyntax-only -verify %s && + +// Test with pch. +// RUN: clang-cc -x=objective-c -emit-pch -o %t %S/objc_import.h && +// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s + +#import "objc_import.h" + +void func() { + TestPCH *xx; + + xx = [TestPCH alloc]; + [xx instMethod]; +} |