aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-07-28 04:50:02 +0000
committerDouglas Gregor <dgregor@apple.com>2011-07-28 04:50:02 +0000
commitb4dc485a2b38ea98ba7da01596fd0e8438120346 (patch)
tree5c1bdf96bf743ad280965639939b72ad579e1ceb /lib
parent65e02fa80e1c185f18e5f81cefc30d75383a7301 (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.cpp46
-rw-r--r--lib/Serialization/ASTWriter.cpp41
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.