aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-12-08 19:11:24 +0000
committerDouglas Gregor <dgregor@apple.com>2011-12-08 19:11:24 +0000
commit77d029f6a24dbf70d97e61757945df53fb250ea0 (patch)
treea5b04a494d0f58aa79d0523e53213a842ffe5dd2 /lib/Serialization
parentd5c3fa29c6a06ed9c74e03b4a96f786cbc156b7c (diff)
Implement umbrella directories for modules, which are similar to
umbrella headers in the sense that all of the headers within that directory (and eventually its subdirectories) are considered to be part of the module with that umbrella directory. However, unlike umbrella headers, which are expected to include all of the headers within their subdirectories, Clang will automatically include all of the headers it finds in the named subdirectory. The intent here is to allow a module map to trivially turn a subdirectory into a module, where the module's structure can mimic the directory structure. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146165 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTReader.cpp24
-rw-r--r--lib/Serialization/ASTWriter.cpp16
2 files changed, 36 insertions, 4 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 21be3aa50c..236c2bd1f5 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3088,7 +3088,7 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) {
break;
}
- case SUBMODULE_UMBRELLA: {
+ case SUBMODULE_UMBRELLA_HEADER: {
if (First) {
Error("missing submodule metadata record at beginning of block");
return Failure;
@@ -3129,6 +3129,28 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) {
break;
}
+ case SUBMODULE_UMBRELLA_DIR: {
+ if (First) {
+ Error("missing submodule metadata record at beginning of block");
+ return Failure;
+ }
+
+ if (!CurrentModule)
+ break;
+
+ StringRef DirName(BlobStart, BlobLen);
+ if (const DirectoryEntry *Umbrella
+ = PP.getFileManager().getDirectory(DirName)) {
+ if (!CurrentModule->getUmbrellaDir())
+ ModMap.setUmbrellaDir(CurrentModule, Umbrella);
+ else if (CurrentModule->getUmbrellaDir() != Umbrella) {
+ Error("mismatched umbrella directories in submodule");
+ return Failure;
+ }
+ }
+ break;
+ }
+
case SUBMODULE_METADATA: {
if (!First) {
Error("submodule metadata record not at beginning of block");
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 1bd9050fe0..83ad885969 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1900,7 +1900,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
unsigned DefinitionAbbrev = Stream.EmitAbbrev(Abbrev);
Abbrev = new BitCodeAbbrev();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA));
+ Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_HEADER));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
unsigned UmbrellaAbbrev = Stream.EmitAbbrev(Abbrev);
@@ -1908,7 +1908,12 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
unsigned HeaderAbbrev = Stream.EmitAbbrev(Abbrev);
-
+
+ Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_DIR));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
+ unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(Abbrev);
+
// Write the submodule metadata block.
RecordData Record;
Record.push_back(getNumberOfModules(WritingModule));
@@ -1943,9 +1948,14 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
// Emit the umbrella header, if there is one.
if (const FileEntry *UmbrellaHeader = Mod->getUmbrellaHeader()) {
Record.clear();
- Record.push_back(SUBMODULE_UMBRELLA);
+ Record.push_back(SUBMODULE_UMBRELLA_HEADER);
Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record,
UmbrellaHeader->getName());
+ } else if (const DirectoryEntry *UmbrellaDir = Mod->getUmbrellaDir()) {
+ Record.clear();
+ Record.push_back(SUBMODULE_UMBRELLA_DIR);
+ Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,
+ UmbrellaDir->getName());
}
// Emit the headers.