diff options
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 164 |
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) { |
