diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-07-28 04:50:02 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-07-28 04:50:02 +0000 |
commit | b4dc485a2b38ea98ba7da01596fd0e8438120346 (patch) | |
tree | 5c1bdf96bf743ad280965639939b72ad579e1ceb /lib | |
parent | 65e02fa80e1c185f18e5f81cefc30d75383a7301 (diff) |
AST serialization support for the Framework in IndexHeaderMapHeader
fields of HeaderFileInfo.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136332 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 46 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 41 |
2 files changed, 69 insertions, 18 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 3eb887367c..6883f44880 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1647,6 +1647,8 @@ namespace { /// inode numbers, so that the search can cope with non-normalized path names /// and symlinks. class HeaderFileInfoTrait { + HeaderSearch *HS; + const char *FrameworkStrings; const char *SearchPath; struct stat SearchPathStatBuf; llvm::Optional<int> SearchPathStatResult; @@ -1669,7 +1671,10 @@ namespace { typedef HeaderFileInfo data_type; - HeaderFileInfoTrait(const char *SearchPath = 0) : SearchPath(SearchPath) { } + HeaderFileInfoTrait(HeaderSearch *HS, + const char *FrameworkStrings, + const char *SearchPath = 0) + : HS(HS), FrameworkStrings(FrameworkStrings), SearchPath(SearchPath) { } static unsigned ComputeHash(const char *path) { return llvm::HashString(llvm::sys::path::filename(path)); @@ -1704,21 +1709,29 @@ namespace { return (const char *)d; } - static data_type ReadData(const internal_key_type, const unsigned char *d, - unsigned DataLen) { + data_type ReadData(const internal_key_type, const unsigned char *d, + unsigned DataLen) { const unsigned char *End = d + DataLen; using namespace clang::io; HeaderFileInfo HFI; unsigned Flags = *d++; - HFI.isImport = (Flags >> 4) & 0x01; - HFI.isPragmaOnce = (Flags >> 3) & 0x01; - HFI.DirInfo = (Flags >> 1) & 0x03; - HFI.Resolved = Flags & 0x01; + HFI.isImport = (Flags >> 5) & 0x01; + HFI.isPragmaOnce = (Flags >> 4) & 0x01; + HFI.DirInfo = (Flags >> 2) & 0x03; + HFI.Resolved = (Flags >> 1) & 0x01; + HFI.IndexHeaderMapHeader = Flags & 0x01; HFI.NumIncludes = ReadUnalignedLE16(d); HFI.ControllingMacroID = ReadUnalignedLE32(d); + if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) { + // The framework offset is 1 greater than the actual offset, + // since 0 is used as an indicator for "no framework name". + StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1); + HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); + } + assert(End == d && "Wrong data length in HeaderFileInfo deserialization"); (void)End; - + // This HeaderFileInfo was externally loaded. HFI.External = true; return HFI; @@ -2424,19 +2437,23 @@ ASTReader::ReadASTBlock(Module &F) { CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I])); break; - case HEADER_SEARCH_TABLE: + case HEADER_SEARCH_TABLE: { F.HeaderFileInfoTableData = BlobStart; F.LocalNumHeaderFileInfos = Record[1]; + F.HeaderFileFrameworkStrings = BlobStart + Record[2]; if (Record[0]) { F.HeaderFileInfoTable = HeaderFileInfoLookupTable::Create( (const unsigned char *)F.HeaderFileInfoTableData + Record[0], - (const unsigned char *)F.HeaderFileInfoTableData); + (const unsigned char *)F.HeaderFileInfoTableData, + HeaderFileInfoTrait(PP? &PP->getHeaderSearchInfo() : 0, + BlobStart + Record[2])); if (PP) PP->getHeaderSearchInfo().SetExternalSource(this); } break; - + } + case FP_PRAGMA_OPTIONS: // Later tables overwrite earlier ones. FPPragmaOptions.swap(Record); @@ -3076,9 +3093,13 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntityAtOffset(uint64_t Offset) { } HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { - HeaderFileInfoTrait Trait(FE->getName()); for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) { Module &F = *(*I); + + HeaderFileInfoTrait Trait(&PP->getHeaderSearchInfo(), + F.HeaderFileFrameworkStrings, + FE->getName()); + HeaderFileInfoLookupTable *Table = static_cast<HeaderFileInfoLookupTable *>(F.HeaderFileInfoTable); if (!Table) @@ -5356,6 +5377,7 @@ Module::Module(ModuleKind Kind) IdentifierLookupTable(0), LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0), LocalNumHeaderFileInfos(0), HeaderFileInfoTableData(0), HeaderFileInfoTable(0), + HeaderFileFrameworkStrings(0), LocalNumSelectors(0), SelectorOffsets(0), SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0), DeclOffsets(0), LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0), diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index d4692b3ed0..9a666910b5 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1272,6 +1272,10 @@ namespace { ASTWriter &Writer; HeaderSearch &HS; + // Keep track of the framework names we've used during serialization. + SmallVector<char, 128> FrameworkStringData; + llvm::StringMap<unsigned> FrameworkNameOffset; + public: HeaderFileInfoTrait(ASTWriter &Writer, HeaderSearch &HS) : Writer(Writer), HS(HS) { } @@ -1295,7 +1299,7 @@ namespace { data_type_ref Data) { unsigned StrLen = strlen(path); clang::io::Emit16(Out, StrLen); - unsigned DataLen = 1 + 2 + 4; + unsigned DataLen = 1 + 2 + 4 + 4; clang::io::Emit8(Out, DataLen); return std::make_pair(StrLen + 1, DataLen); } @@ -1309,10 +1313,11 @@ namespace { using namespace clang::io; uint64_t Start = Out.tell(); (void)Start; - unsigned char Flags = (Data.isImport << 4) - | (Data.isPragmaOnce << 3) - | (Data.DirInfo << 1) - | Data.Resolved; + unsigned char Flags = (Data.isImport << 5) + | (Data.isPragmaOnce << 4) + | (Data.DirInfo << 2) + | (Data.Resolved << 1) + | Data.IndexHeaderMapHeader; Emit8(Out, (uint8_t)Flags); Emit16(Out, (uint16_t) Data.NumIncludes); @@ -1320,8 +1325,29 @@ namespace { Emit32(Out, (uint32_t)Data.ControllingMacroID); else Emit32(Out, (uint32_t)Writer.getIdentifierRef(Data.ControllingMacro)); + + unsigned Offset = 0; + if (!Data.Framework.empty()) { + // If this header refers into a framework, save the framework name. + llvm::StringMap<unsigned>::iterator Pos + = FrameworkNameOffset.find(Data.Framework); + if (Pos == FrameworkNameOffset.end()) { + Offset = FrameworkStringData.size() + 1; + FrameworkStringData.append(Data.Framework.begin(), + Data.Framework.end()); + FrameworkStringData.push_back(0); + + FrameworkNameOffset[Data.Framework] = Offset; + } else + Offset = Pos->second; + } + Emit32(Out, Offset); + assert(Out.tell() - Start == DataLen && "Wrong data length"); } + + const char *strings_begin() const { return FrameworkStringData.begin(); } + const char *strings_end() const { return FrameworkStringData.end(); } }; } // end anonymous namespace @@ -1381,14 +1407,17 @@ void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, StringRef isysroot) { Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); unsigned TableAbbrev = Stream.EmitAbbrev(Abbrev); - // Write the stat cache + // Write the header search table RecordData Record; Record.push_back(HEADER_SEARCH_TABLE); Record.push_back(BucketOffset); Record.push_back(NumHeaderSearchEntries); + Record.push_back(TableData.size()); + TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end()); Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData.str()); // Free all of the strings we had to duplicate. |