summaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp164
1 files changed, 144 insertions, 20 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 66c207ad9243..a1972f5c6496 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -132,6 +132,18 @@ static StringRef bytes(const SmallVectorImpl<T> &v) {
sizeof(T) * v.size());
}
+static std::string bytes(const std::vector<bool> &V) {
+ std::string Str;
+ Str.reserve(V.size() / 8);
+ for (unsigned I = 0, E = V.size(); I < E;) {
+ char Byte = 0;
+ for (unsigned Bit = 0; Bit < 8 && I < E; ++Bit, ++I)
+ Byte |= V[I] << Bit;
+ Str += Byte;
+ }
+ return Str;
+}
+
//===----------------------------------------------------------------------===//
// Type serialization
//===----------------------------------------------------------------------===//
@@ -149,6 +161,59 @@ static TypeCode getTypeCodeForTypeClass(Type::TypeClass id) {
namespace {
+std::set<const FileEntry *> GetAllModuleMaps(const HeaderSearch &HS,
+ Module *RootModule) {
+ std::set<const FileEntry *> ModuleMaps{};
+ std::set<Module *> ProcessedModules;
+ SmallVector<Module *> ModulesToProcess{RootModule};
+
+ SmallVector<const FileEntry *, 16> FilesByUID;
+ HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
+
+ if (FilesByUID.size() > HS.header_file_size())
+ FilesByUID.resize(HS.header_file_size());
+
+ for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
+ const FileEntry *File = FilesByUID[UID];
+ if (!File)
+ continue;
+
+ const HeaderFileInfo *HFI =
+ HS.getExistingFileInfo(File, /*WantExternal*/ false);
+ if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
+ continue;
+
+ for (const auto &KH : HS.findAllModulesForHeader(File)) {
+ if (!KH.getModule())
+ continue;
+ ModulesToProcess.push_back(KH.getModule());
+ }
+ }
+
+ while (!ModulesToProcess.empty()) {
+ auto *CurrentModule = ModulesToProcess.pop_back_val();
+ ProcessedModules.insert(CurrentModule);
+
+ auto *ModuleMapFile =
+ HS.getModuleMap().getModuleMapFileForUniquing(CurrentModule);
+ if (!ModuleMapFile) {
+ continue;
+ }
+
+ ModuleMaps.insert(ModuleMapFile);
+
+ for (auto *ImportedModule : (CurrentModule)->Imports) {
+ if (!ImportedModule ||
+ ProcessedModules.find(ImportedModule) != ProcessedModules.end()) {
+ continue;
+ }
+ ModulesToProcess.push_back(ImportedModule);
+ }
+ }
+
+ return ModuleMaps;
+}
+
class ASTTypeWriter {
ASTWriter &Writer;
ASTWriter::RecordData Record;
@@ -1050,6 +1115,8 @@ ASTWriter::createSignature(StringRef AllBytes, StringRef ASTBlockBytes) {
ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
ASTContext &Context) {
+ using namespace llvm;
+
// Flush first to prepare the PCM hash (signature).
Stream.FlushToWord();
auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3;
@@ -1093,10 +1160,24 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
// Note: we don't serialize the log or serialization file names, because they
// are generally transient files and will almost always be overridden.
Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
+ Record.clear();
// Write out the diagnostic/pragma mappings.
WritePragmaDiagnosticMappings(Diags, /* isModule = */ WritingModule);
+ // Header search entry usage.
+ auto HSEntryUsage = PP.getHeaderSearchInfo().computeUserEntryUsage();
+ auto Abbrev = std::make_shared<BitCodeAbbrev>();
+ Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_ENTRY_USAGE));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Number of bits.
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Bit vector.
+ unsigned HSUsageAbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+ {
+ RecordData::value_type Record[] = {HEADER_SEARCH_ENTRY_USAGE,
+ HSEntryUsage.size()};
+ Stream.EmitRecordWithBlob(HSUsageAbbrevCode, Record, bytes(HSEntryUsage));
+ }
+
// Leave the options block.
Stream.ExitBlock();
return Signature;
@@ -1396,9 +1477,15 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir);
}
+ std::set<const FileEntry *> AffectingModuleMaps;
+ if (WritingModule) {
+ AffectingModuleMaps =
+ GetAllModuleMaps(PP.getHeaderSearchInfo(), WritingModule);
+ }
+
WriteInputFiles(Context.SourceMgr,
PP.getHeaderSearchInfo().getHeaderSearchOpts(),
- PP.getLangOpts().Modules);
+ AffectingModuleMaps);
Stream.ExitBlock();
}
@@ -1416,9 +1503,9 @@ struct InputFileEntry {
} // namespace
-void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
- HeaderSearchOptions &HSOpts,
- bool Modules) {
+void ASTWriter::WriteInputFiles(
+ SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
+ std::set<const FileEntry *> &AffectingModuleMaps) {
using namespace llvm;
Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4);
@@ -1458,6 +1545,16 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
if (!Cache->OrigEntry)
continue;
+ if (isModuleMap(File.getFileCharacteristic()) &&
+ !isSystem(File.getFileCharacteristic()) &&
+ !AffectingModuleMaps.empty() &&
+ AffectingModuleMaps.find(Cache->OrigEntry) ==
+ AffectingModuleMaps.end()) {
+ SkippedModuleMaps.insert(Cache->OrigEntry);
+ // Do not emit modulemaps that do not affect current module.
+ continue;
+ }
+
InputFileEntry Entry;
Entry.File = Cache->OrigEntry;
Entry.IsSystemFile = isSystem(File.getFileCharacteristic());
@@ -1971,11 +2068,17 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
Record.push_back(SLoc->getOffset() - 2);
if (SLoc->isFile()) {
const SrcMgr::FileInfo &File = SLoc->getFile();
+ const SrcMgr::ContentCache *Content = &File.getContentCache();
+ if (Content->OrigEntry && !SkippedModuleMaps.empty() &&
+ SkippedModuleMaps.find(Content->OrigEntry) !=
+ SkippedModuleMaps.end()) {
+ // Do not emit files that were not listed as inputs.
+ continue;
+ }
AddSourceLocation(File.getIncludeLoc(), Record);
Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
Record.push_back(File.hasLineDirectives());
- const SrcMgr::ContentCache *Content = &File.getContentCache();
bool EmitBlob = false;
if (Content->OrigEntry) {
assert(Content->OrigEntry == Content->ContentsEntry &&
@@ -3017,11 +3120,11 @@ public:
unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts
for (const ObjCMethodList *Method = &Methods.Instance; Method;
Method = Method->getNext())
- if (Method->getMethod())
+ if (ShouldWriteMethodListNode(Method))
DataLen += 4;
for (const ObjCMethodList *Method = &Methods.Factory; Method;
Method = Method->getNext())
- if (Method->getMethod())
+ if (ShouldWriteMethodListNode(Method))
DataLen += 4;
return emitULEBKeyDataLength(KeyLen, DataLen, Out);
}
@@ -3052,13 +3155,13 @@ public:
unsigned NumInstanceMethods = 0;
for (const ObjCMethodList *Method = &Methods.Instance; Method;
Method = Method->getNext())
- if (Method->getMethod())
+ if (ShouldWriteMethodListNode(Method))
++NumInstanceMethods;
unsigned NumFactoryMethods = 0;
for (const ObjCMethodList *Method = &Methods.Factory; Method;
Method = Method->getNext())
- if (Method->getMethod())
+ if (ShouldWriteMethodListNode(Method))
++NumFactoryMethods;
unsigned InstanceBits = Methods.Instance.getBits();
@@ -3079,15 +3182,20 @@ public:
LE.write<uint16_t>(FullFactoryBits);
for (const ObjCMethodList *Method = &Methods.Instance; Method;
Method = Method->getNext())
- if (Method->getMethod())
+ if (ShouldWriteMethodListNode(Method))
LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));
for (const ObjCMethodList *Method = &Methods.Factory; Method;
Method = Method->getNext())
- if (Method->getMethod())
+ if (ShouldWriteMethodListNode(Method))
LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));
assert(Out.tell() - Start == DataLen && "Data length is wrong");
}
+
+private:
+ static bool ShouldWriteMethodListNode(const ObjCMethodList *Node) {
+ return (Node->getMethod() && !Node->getMethod()->isFromASTFile());
+ }
};
} // namespace
@@ -3130,15 +3238,21 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
if (Chain && ID < FirstSelectorID) {
// Selector already exists. Did it change?
bool changed = false;
- for (ObjCMethodList *M = &Data.Instance;
- !changed && M && M->getMethod(); M = M->getNext()) {
- if (!M->getMethod()->isFromASTFile())
+ for (ObjCMethodList *M = &Data.Instance; M && M->getMethod();
+ M = M->getNext()) {
+ if (!M->getMethod()->isFromASTFile()) {
changed = true;
+ Data.Instance = *M;
+ break;
+ }
}
- for (ObjCMethodList *M = &Data.Factory; !changed && M && M->getMethod();
+ for (ObjCMethodList *M = &Data.Factory; M && M->getMethod();
M = M->getNext()) {
- if (!M->getMethod()->isFromASTFile())
+ if (!M->getMethod()->isFromASTFile()) {
changed = true;
+ Data.Factory = *M;
+ break;
+ }
}
if (!changed)
continue;
@@ -3390,11 +3504,9 @@ public:
// Only emit declarations that aren't from a chained PCH, though.
SmallVector<NamedDecl *, 16> Decls(IdResolver.begin(II),
IdResolver.end());
- for (SmallVectorImpl<NamedDecl *>::reverse_iterator D = Decls.rbegin(),
- DEnd = Decls.rend();
- D != DEnd; ++D)
+ for (NamedDecl *D : llvm::reverse(Decls))
LE.write<uint32_t>(
- Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), *D)));
+ Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), D)));
}
}
};
@@ -4987,6 +5099,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
auto *A = D->getAttr<OMPAllocateDeclAttr>();
Record.push_back(A->getAllocatorType());
Record.AddStmt(A->getAllocator());
+ Record.AddStmt(A->getAlignment());
Record.AddSourceRange(A->getRange());
break;
}
@@ -6191,6 +6304,11 @@ void OMPClauseWriter::VisitOMPFilterClause(OMPFilterClause *C) {
Record.AddSourceLocation(C->getLParenLoc());
}
+void OMPClauseWriter::VisitOMPAlignClause(OMPAlignClause *C) {
+ Record.AddStmt(C->getAlignment());
+ Record.AddSourceLocation(C->getLParenLoc());
+}
+
void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
Record.push_back(C->varlist_size());
Record.AddSourceLocation(C->getLParenLoc());
@@ -6693,6 +6811,12 @@ void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) {
Record.AddStmt(E);
}
+void OMPClauseWriter::VisitOMPBindClause(OMPBindClause *C) {
+ Record.writeEnum(C->getBindKind());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getBindKindLoc());
+}
+
void ASTRecordWriter::writeOMPTraitInfo(const OMPTraitInfo *TI) {
writeUInt32(TI->Sets.size());
for (const auto &Set : TI->Sets) {