diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Serialization | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r-- | clang/lib/Serialization/ASTCommon.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 2037 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 133 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 459 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 345 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 49 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 270 | ||||
-rw-r--r-- | clang/lib/Serialization/GeneratePCH.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Serialization/GlobalModuleIndex.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 11 |
10 files changed, 2332 insertions, 1006 deletions
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index cdb5b17022c2..bf583b02f96b 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -240,9 +240,21 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::BuiltinFn: ID = PREDEF_TYPE_BUILTIN_FN; break; + case BuiltinType::IncompleteMatrixIdx: + ID = PREDEF_TYPE_INCOMPLETE_MATRIX_IDX; + break; case BuiltinType::OMPArraySection: ID = PREDEF_TYPE_OMP_ARRAY_SECTION; break; + case BuiltinType::OMPArrayShaping: + ID = PREDEF_TYPE_OMP_ARRAY_SHAPING; + break; + case BuiltinType::OMPIterator: + ID = PREDEF_TYPE_OMP_ITERATOR; + break; + case BuiltinType::BFloat16: + ID = PREDEF_TYPE_BFLOAT16_ID; + break; } return TypeIdx(ID); @@ -365,6 +377,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::IndirectField: case Decl::Field: case Decl::MSProperty: + case Decl::MSGuid: case Decl::ObjCIvar: case Decl::ObjCAtDefsField: case Decl::NonTypeTemplateParm: @@ -402,6 +415,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::Binding: case Decl::Concept: case Decl::LifetimeExtendedTemporary: + case Decl::RequiresExprBody: return false; // These indirectly derive from Redeclarable<T> but are not actually diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 19e7ebe03a1f..4a1a995204e5 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -89,6 +89,7 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -139,6 +140,7 @@ using namespace clang; using namespace clang::serialization; using namespace clang::serialization::reader; using llvm::BitstreamCursor; +using llvm::RoundingMode; //===----------------------------------------------------------------------===// // ChainedASTReaderListener implementation @@ -1334,6 +1336,7 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) { Error(std::move(Err)); return true; } + F.SourceManagerBlockStartOffset = SLocEntryCursor.GetCurrentBitNo(); RecordData Record; while (true) { @@ -1411,7 +1414,7 @@ resolveFileRelativeToOriginalDir(const std::string &Filename, path::append(currPCHPath, ".."); path::append(currPCHPath, fileDirI, fileDirE); path::append(currPCHPath, path::filename(Filename)); - return currPCHPath.str(); + return std::string(currPCHPath.str()); } bool ASTReader::ReadSLocEntry(int ID) { @@ -1468,6 +1471,7 @@ bool ASTReader::ReadSLocEntry(int ID) { ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second; if (llvm::Error Err = F->SLocEntryCursor.JumpToBit( + F->SLocEntryOffsetsBase + F->SLocEntryOffsets[ID - F->SLocEntryBaseID])) { Error(std::move(Err)); return true; @@ -1625,13 +1629,17 @@ SourceLocation ASTReader::getImportLocation(ModuleFile *F) { /// Enter a subblock of the specified BlockID with the specified cursor. Read /// the abbreviations that are at the top of the block and then leave the cursor /// pointing into the block. -bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) { +bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID, + uint64_t *StartOfBlockOffset) { if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) { // FIXME this drops errors on the floor. consumeError(std::move(Err)); return true; } + if (StartOfBlockOffset) + *StartOfBlockOffset = Cursor.GetCurrentBitNo(); + while (true) { uint64_t Offset = Cursor.GetCurrentBitNo(); Expected<unsigned> MaybeCode = Cursor.ReadCode(); @@ -1838,7 +1846,7 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { return nullptr; } - std::string Resolved = Key.Filename; + std::string Resolved = std::string(Key.Filename); Reader.ResolveImportedPath(M, Resolved); if (auto File = FileMgr.getFile(Resolved)) return *File; @@ -1913,13 +1921,13 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, ModuleMap &ModMap = Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - std::string Filename = key.Filename; + std::string Filename = std::string(key.Filename); if (key.Imported) Reader.ResolveImportedPath(M, Filename); // FIXME: This is not always the right filename-as-written, but we're not // going to use this information to rebuild the module, so it doesn't make // a lot of difference. - Module::Header H = { key.Filename, *FileMgr.getFile(Filename) }; + Module::Header H = {std::string(key.Filename), *FileMgr.getFile(Filename)}; ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true); HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader); } @@ -1930,9 +1938,8 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, return HFI; } -void ASTReader::addPendingMacro(IdentifierInfo *II, - ModuleFile *M, - uint64_t MacroDirectivesOffset) { +void ASTReader::addPendingMacro(IdentifierInfo *II, ModuleFile *M, + uint32_t MacroDirectivesOffset) { assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard"); PendingMacroIDs[II].push_back(PendingMacroInfo(M, MacroDirectivesOffset)); } @@ -2097,7 +2104,8 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, BitstreamCursor &Cursor = M.MacroCursor; SavedStreamPosition SavedPosition(Cursor); - if (llvm::Error Err = Cursor.JumpToBit(PMInfo.MacroDirectivesOffset)) { + if (llvm::Error Err = + Cursor.JumpToBit(M.MacroOffsetsBase + PMInfo.MacroDirectivesOffset)) { Error(std::move(Err)); return; } @@ -2248,7 +2256,7 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) { R.Overridden = static_cast<bool>(Record[3]); R.Transient = static_cast<bool>(Record[4]); R.TopLevelModuleMap = static_cast<bool>(Record[5]); - R.Filename = Blob; + R.Filename = std::string(Blob); ResolveImportedPath(F, R.Filename); Expected<llvm::BitstreamEntry> MaybeEntry = Cursor.advance(); @@ -2309,7 +2317,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { if (File == nullptr && !F.OriginalDir.empty() && !F.BaseDirectory.empty() && F.OriginalDir != F.BaseDirectory) { std::string Resolved = resolveFileRelativeToOriginalDir( - Filename, F.OriginalDir, F.BaseDirectory); + std::string(Filename), F.OriginalDir, F.BaseDirectory); if (!Resolved.empty()) if (auto FE = FileMgr.getFile(Resolved)) File = *FE; @@ -2788,10 +2796,10 @@ ASTReader::ReadControlBlock(ModuleFile &F, ReadUntranslatedSourceLocation(Record[Idx++]); off_t StoredSize = (off_t)Record[Idx++]; time_t StoredModTime = (time_t)Record[Idx++]; - ASTFileSignature StoredSignature = { - {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++]}}}; + auto FirstSignatureByte = Record.begin() + Idx; + ASTFileSignature StoredSignature = ASTFileSignature::create( + FirstSignatureByte, FirstSignatureByte + ASTFileSignature::size); + Idx += ASTFileSignature::size; std::string ImportedName = ReadString(Record, Idx); std::string ImportedFile; @@ -2844,7 +2852,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, case ORIGINAL_FILE: F.OriginalSourceFileID = FileID::get(Record[0]); - F.ActualOriginalSourceFileName = Blob; + F.ActualOriginalSourceFileName = std::string(Blob); F.OriginalSourceFileName = F.ActualOriginalSourceFileName; ResolveImportedPath(F, F.OriginalSourceFileName); break; @@ -2854,11 +2862,11 @@ ASTReader::ReadControlBlock(ModuleFile &F, break; case ORIGINAL_PCH_DIR: - F.OriginalDir = Blob; + F.OriginalDir = std::string(Blob); break; case MODULE_NAME: - F.ModuleName = Blob; + F.ModuleName = std::string(Blob); Diag(diag::remark_module_import) << F.ModuleName << F.FileName << (ImportedBy ? true : false) << (ImportedBy ? StringRef(ImportedBy->ModuleName) : StringRef()); @@ -2897,9 +2905,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, return OutOfDate; } } - F.BaseDirectory = M->Directory->getName(); + F.BaseDirectory = std::string(M->Directory->getName()); } else { - F.BaseDirectory = Blob; + F.BaseDirectory = std::string(Blob); } break; } @@ -2930,6 +2938,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Error(std::move(Err)); return Failure; } + F.ASTBlockStartOffset = Stream.GetCurrentBitNo(); // Read all of the records and blocks for the AST file. RecordData Record; @@ -2970,7 +2979,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Error(std::move(Err)); return Failure; } - if (ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) { + if (ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID, + &F.DeclsBlockStartOffset)) { Error("malformed block record in AST file"); return Failure; } @@ -3096,7 +3106,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Error("duplicate TYPE_OFFSET record in AST file"); return Failure; } - F.TypeOffsets = (const uint32_t *)Blob.data(); + F.TypeOffsets = reinterpret_cast<const UnderalignedInt64 *>(Blob.data()); F.LocalNumTypes = Record[0]; unsigned LocalBaseTypeIndex = Record[1]; F.BaseTypeIndex = getTotalNumTypes(); @@ -3375,6 +3385,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.SLocEntryOffsets = (const uint32_t *)Blob.data(); F.LocalNumSLocEntries = Record[0]; unsigned SLocSpaceSize = Record[1]; + F.SLocEntryOffsetsBase = Record[2] + F.SourceManagerBlockStartOffset; std::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) = SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries, SLocSpaceSize); @@ -3693,6 +3704,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.MacroOffsets = (const uint32_t *)Blob.data(); F.LocalNumMacros = Record[0]; unsigned LocalBaseMacroID = Record[1]; + F.MacroOffsetsBase = Record[2] + F.ASTBlockStartOffset; F.BaseMacroID = getTotalNumMacros(); if (F.LocalNumMacros > 0) { @@ -3774,6 +3786,34 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; } + + case FLOAT_CONTROL_PRAGMA_OPTIONS: { + if (Record.size() < 3) { + Error("invalid pragma pack record"); + return Failure; + } + FpPragmaCurrentValue = Record[0]; + FpPragmaCurrentLocation = ReadSourceLocation(F, Record[1]); + unsigned NumStackEntries = Record[2]; + unsigned Idx = 3; + // Reset the stack when importing a new module. + FpPragmaStack.clear(); + for (unsigned I = 0; I < NumStackEntries; ++I) { + FpPragmaStackEntry Entry; + Entry.Value = Record[Idx++]; + Entry.Location = ReadSourceLocation(F, Record[Idx++]); + Entry.PushLocation = ReadSourceLocation(F, Record[Idx++]); + FpPragmaStrings.push_back(ReadString(Record, Idx)); + Entry.SlotLabel = FpPragmaStrings.back(); + FpPragmaStack.push_back(Entry); + } + break; + } + + case DECLS_TO_CHECK_FOR_DEFERRED_DIAGS: + for (unsigned I = 0, N = Record.size(); I != N; ++I) + DeclsToCheckForDeferredDiags.push_back(getGlobalDeclID(F, Record[I])); + break; } } } @@ -3805,21 +3845,22 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { while (Data < DataEnd) { // FIXME: Looking up dependency modules by filename is horrible. Let's - // start fixing this with prebuilt and explicit modules and see how it - // goes... + // start fixing this with prebuilt, explicit and implicit modules and see + // how it goes... using namespace llvm::support; ModuleKind Kind = static_cast<ModuleKind>( endian::readNext<uint8_t, little, unaligned>(Data)); uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data); StringRef Name = StringRef((const char*)Data, Len); Data += Len; - ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule - ? ModuleMgr.lookupByModuleName(Name) - : ModuleMgr.lookupByFileName(Name)); + ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule || + Kind == MK_ImplicitModule + ? ModuleMgr.lookupByModuleName(Name) + : ModuleMgr.lookupByFileName(Name)); if (!OM) { std::string Msg = "SourceLocation remap refers to unknown module, cannot find "; - Msg.append(Name); + Msg.append(std::string(Name)); Error(Msg); return; } @@ -3998,7 +4039,7 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) { assert(Owner->NameVisibility != Module::Hidden && "nothing to make visible?"); for (Decl *D : Names) { - bool wasHidden = D->isHidden(); + bool wasHidden = !D->isUnconditionallyVisible(); D->setVisibleDespiteOwningModule(); if (wasHidden && SemaObj) { @@ -4024,8 +4065,8 @@ void ASTReader::makeModuleVisible(Module *Mod, continue; } - if (!Mod->isAvailable()) { - // Modules that aren't available cannot be made visible. + if (Mod->isUnimportable()) { + // Modules that aren't importable cannot be made visible. continue; } @@ -4060,9 +4101,9 @@ void ASTReader::makeModuleVisible(Module *Mod, /// visible. void ASTReader::mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef) { - if (Def->isHidden()) { + if (!Def->isUnconditionallyVisible()) { // If MergedDef is visible or becomes visible, make the definition visible. - if (!MergedDef->isHidden()) + if (MergedDef->isUnconditionallyVisible()) Def->setVisibleDespiteOwningModule(); else { getContext().mergeDefinitionIntoModule( @@ -4702,7 +4743,12 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( switch ((UnhashedControlBlockRecordTypes)MaybeRecordType.get()) { case SIGNATURE: if (F) - std::copy(Record.begin(), Record.end(), F->Signature.data()); + F->Signature = ASTFileSignature::create(Record.begin(), Record.end()); + break; + case AST_BLOCK_HASH: + if (F) + F->ASTBlockHash = + ASTFileSignature::create(Record.begin(), Record.end()); break; case DIAGNOSTIC_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; @@ -4991,8 +5037,8 @@ static ASTFileSignature readASTFileSignature(StringRef PCH) { return ASTFileSignature(); } if (SIGNATURE == MaybeRecord.get()) - return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2], - (uint32_t)Record[3], (uint32_t)Record[4]}}}; + return ASTFileSignature::create(Record.begin(), + Record.begin() + ASTFileSignature::size); } } @@ -5071,13 +5117,11 @@ namespace { SimplePCHValidator(const LangOptions &ExistingLangOpts, const TargetOptions &ExistingTargetOpts, const PreprocessorOptions &ExistingPPOpts, - StringRef ExistingModuleCachePath, - FileManager &FileMgr) - : ExistingLangOpts(ExistingLangOpts), - ExistingTargetOpts(ExistingTargetOpts), - ExistingPPOpts(ExistingPPOpts), - ExistingModuleCachePath(ExistingModuleCachePath), - FileMgr(FileMgr) {} + StringRef ExistingModuleCachePath, FileManager &FileMgr) + : ExistingLangOpts(ExistingLangOpts), + ExistingTargetOpts(ExistingTargetOpts), + ExistingPPOpts(ExistingPPOpts), + ExistingModuleCachePath(ExistingModuleCachePath), FileMgr(FileMgr) {} bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, bool AllowCompatibleDifferences) override { @@ -5221,7 +5265,7 @@ bool ASTReader::readASTFileControlBlock( Listener.ReadModuleName(Blob); break; case MODULE_DIRECTORY: - ModuleDir = Blob; + ModuleDir = std::string(Blob); break; case MODULE_MAP_FILE: { unsigned Idx = 0; @@ -5273,7 +5317,7 @@ bool ASTReader::readASTFileControlBlock( break; case INPUT_FILE: bool Overridden = static_cast<bool>(Record[3]); - std::string Filename = Blob; + std::string Filename = std::string(Blob); ResolveImportedPath(Filename, ModuleDir); shouldContinue = Listener.visitInputFile( Filename, isSystemFile, Overridden, /*IsExplicitModule*/false); @@ -5292,7 +5336,9 @@ bool ASTReader::readASTFileControlBlock( unsigned Idx = 0, N = Record.size(); while (Idx < N) { // Read information about the AST file. - Idx += 1+1+1+1+5; // Kind, ImportLoc, Size, ModTime, Signature + Idx += + 1 + 1 + 1 + 1 + + ASTFileSignature::size; // Kind, ImportLoc, Size, ModTime, Signature std::string ModuleName = ReadString(Record, Idx); std::string Filename = ReadString(Record, Idx); ResolveImportedPath(Filename, ModuleDir); @@ -5532,14 +5578,14 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // imported module file. CurrentModule->Requirements.clear(); CurrentModule->MissingHeaders.clear(); - CurrentModule->IsMissingRequirement = - ParentModule && ParentModule->IsMissingRequirement; - CurrentModule->IsAvailable = !CurrentModule->IsMissingRequirement; + CurrentModule->IsUnimportable = + ParentModule && ParentModule->IsUnimportable; + CurrentModule->IsAvailable = !CurrentModule->IsUnimportable; break; } case SUBMODULE_UMBRELLA_HEADER: { - std::string Filename = Blob; + std::string Filename = std::string(Blob); ResolveImportedPath(F, Filename); if (auto Umbrella = PP.getFileManager().getFile(Filename)) { if (!CurrentModule->getUmbrellaHeader()) @@ -5572,7 +5618,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; case SUBMODULE_UMBRELLA_DIR: { - std::string Dirname = Blob; + std::string Dirname = std::string(Blob); ResolveImportedPath(F, Dirname); if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) { if (!CurrentModule->getUmbrellaDir()) @@ -5642,7 +5688,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case SUBMODULE_LINK_LIBRARY: ModMap.resolveLinkAsDependencies(CurrentModule); CurrentModule->LinkLibraries.push_back( - Module::LinkLibrary(Blob, Record[0])); + Module::LinkLibrary(std::string(Blob), Record[0])); break; case SUBMODULE_CONFIG_MACRO: @@ -5903,8 +5949,8 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { } SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor); - if (llvm::Error Err = - M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset)) { + if (llvm::Error Err = M.PreprocessorDetailCursor.JumpToBit( + M.MacroOffsetsBase + PPOffs.BitOffset)) { Error(std::move(Err)); return nullptr; } @@ -6317,7 +6363,9 @@ ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) { GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index); assert(I != GlobalTypeMap.end() && "Corrupted global type map"); ModuleFile *M = I->second; - return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex]); + return RecordLocation( + M, M->TypeOffsets[Index - M->BaseTypeIndex].getBitOffset() + + M->DeclsBlockStartOffset); } static llvm::Optional<Type::TypeClass> getTypeClassForCode(TypeCode code) { @@ -6523,6 +6571,21 @@ void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { TL.setNameLoc(readSourceLocation()); } +void TypeLocReader::VisitConstantMatrixTypeLoc(ConstantMatrixTypeLoc TL) { + TL.setAttrNameLoc(readSourceLocation()); + TL.setAttrOperandParensRange(Reader.readSourceRange()); + TL.setAttrRowOperand(Reader.readExpr()); + TL.setAttrColumnOperand(Reader.readExpr()); +} + +void TypeLocReader::VisitDependentSizedMatrixTypeLoc( + DependentSizedMatrixTypeLoc TL) { + TL.setAttrNameLoc(readSourceLocation()); + TL.setAttrOperandParensRange(Reader.readSourceRange()); + TL.setAttrRowOperand(Reader.readExpr()); + TL.setAttrColumnOperand(Reader.readExpr()); +} + void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) { TL.setLocalRangeBegin(readSourceLocation()); TL.setLParenLoc(readSourceLocation()); @@ -6576,6 +6639,17 @@ void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) { TL.setNameLoc(readSourceLocation()); + if (Reader.readBool()) { + TL.setNestedNameSpecifierLoc(ReadNestedNameSpecifierLoc()); + TL.setTemplateKWLoc(readSourceLocation()); + TL.setConceptNameLoc(readSourceLocation()); + TL.setFoundDecl(Reader.readDeclAs<NamedDecl>()); + TL.setLAngleLoc(readSourceLocation()); + TL.setRAngleLoc(readSourceLocation()); + for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) + TL.setArgLocInfo(i, Reader.readTemplateArgumentLocInfo( + TL.getTypePtr()->getArg(i).getKind())); + } } void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc( @@ -6700,6 +6774,15 @@ void TypeLocReader::VisitPipeTypeLoc(PipeTypeLoc TL) { TL.setKWLoc(readSourceLocation()); } +void TypeLocReader::VisitExtIntTypeLoc(clang::ExtIntTypeLoc TL) { + TL.setNameLoc(readSourceLocation()); +} +void TypeLocReader::VisitDependentExtIntTypeLoc( + clang::DependentExtIntTypeLoc TL) { + TL.setNameLoc(readSourceLocation()); +} + + void ASTRecordReader::readTypeLoc(TypeLoc TL) { TypeLocReader TLR(*this); for (; !TL.isNull(); TL = TL.getNextTypeLoc()) @@ -6778,6 +6861,9 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_INT128_ID: T = Context.Int128Ty; break; + case PREDEF_TYPE_BFLOAT16_ID: + T = Context.BFloat16Ty; + break; case PREDEF_TYPE_HALF_ID: T = Context.HalfTy; break; @@ -6941,9 +7027,18 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_BUILTIN_FN: T = Context.BuiltinFnTy; break; + case PREDEF_TYPE_INCOMPLETE_MATRIX_IDX: + T = Context.IncompleteMatrixIdxTy; + break; case PREDEF_TYPE_OMP_ARRAY_SECTION: T = Context.OMPArraySectionTy; break; + case PREDEF_TYPE_OMP_ARRAY_SHAPING: + T = Context.OMPArraySectionTy; + break; + case PREDEF_TYPE_OMP_ITERATOR: + T = Context.OMPIteratorTy; + break; #define SVE_TYPE(Name, Id, SingletonId) \ case PREDEF_TYPE_##Id##_ID: \ T = Context.SingletonId; \ @@ -7266,6 +7361,9 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { case PREDEF_DECL_BUILTIN_MS_VA_LIST_ID: return Context.getBuiltinMSVaListDecl(); + case PREDEF_DECL_BUILTIN_MS_GUID_ID: + return Context.getMSGuidTagDecl(); + case PREDEF_DECL_EXTERN_C_CONTEXT_ID: return Context.getExternCContextDecl(); @@ -7746,7 +7844,9 @@ void ASTReader::InitializeSema(Sema &S) { // FIXME: What happens if these are changed by a module import? if (!FPPragmaOptions.empty()) { assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS"); - SemaObj->FPFeatures = FPOptions(FPPragmaOptions[0]); + FPOptionsOverride NewOverrides(FPPragmaOptions[0]); + SemaObj->CurFPFeatures = + NewOverrides.applyOverrides(SemaObj->getLangOpts()); } SemaObj->OpenCLFeatures.copy(OpenCLExtensions); @@ -7816,6 +7916,34 @@ void ASTReader::UpdateSema() { SemaObj->PackStack.CurrentPragmaLocation = PragmaPackCurrentLocation; } } + if (FpPragmaCurrentValue) { + // The bottom of the stack might have a default value. It must be adjusted + // to the current value to ensure that fp-pragma state is preserved after + // popping entries that were included/imported from a PCH/module. + bool DropFirst = false; + if (!FpPragmaStack.empty() && FpPragmaStack.front().Location.isInvalid()) { + assert(FpPragmaStack.front().Value == + SemaObj->FpPragmaStack.DefaultValue && + "Expected a default pragma float_control value"); + SemaObj->FpPragmaStack.Stack.emplace_back( + FpPragmaStack.front().SlotLabel, SemaObj->FpPragmaStack.CurrentValue, + SemaObj->FpPragmaStack.CurrentPragmaLocation, + FpPragmaStack.front().PushLocation); + DropFirst = true; + } + for (const auto &Entry : + llvm::makeArrayRef(FpPragmaStack).drop_front(DropFirst ? 1 : 0)) + SemaObj->FpPragmaStack.Stack.emplace_back( + Entry.SlotLabel, Entry.Value, Entry.Location, Entry.PushLocation); + if (FpPragmaCurrentLocation.isInvalid()) { + assert(*FpPragmaCurrentValue == SemaObj->FpPragmaStack.DefaultValue && + "Expected a default pragma float_control value"); + // Keep the current values. + } else { + SemaObj->FpPragmaStack.CurrentValue = *FpPragmaCurrentValue; + SemaObj->FpPragmaStack.CurrentPragmaLocation = FpPragmaCurrentLocation; + } + } } IdentifierInfo *ASTReader::get(StringRef Name) { @@ -8172,6 +8300,19 @@ void ASTReader::ReadUnusedLocalTypedefNameCandidates( UnusedLocalTypedefNameCandidates.clear(); } +void ASTReader::ReadDeclsToCheckForDeferredDiags( + llvm::SmallVector<Decl *, 4> &Decls) { + for (unsigned I = 0, N = DeclsToCheckForDeferredDiags.size(); I != N; + ++I) { + auto *D = dyn_cast_or_null<Decl>( + GetDecl(DeclsToCheckForDeferredDiags[I])); + if (D) + Decls.push_back(D); + } + DeclsToCheckForDeferredDiags.clear(); +} + + void ASTReader::ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) { if (ReferencedSelectorsData.empty()) @@ -8390,7 +8531,8 @@ MacroInfo *ASTReader::getMacro(MacroID ID) { assert(I != GlobalMacroMap.end() && "Corrupted global macro map"); ModuleFile *M = I->second; unsigned Index = ID - M->BaseMacroID; - MacrosLoaded[ID] = ReadMacroRecord(*M, M->MacroOffsets[Index]); + MacrosLoaded[ID] = + ReadMacroRecord(*M, M->MacroOffsetsBase + M->MacroOffsets[Index]); if (DeserializationListener) DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS, @@ -8483,10 +8625,10 @@ unsigned ASTReader::getModuleFileID(ModuleFile *F) { return (I - PCHModules.end()) << 1; } -llvm::Optional<ExternalASTSource::ASTSourceDescriptor> +llvm::Optional<ASTSourceDescriptor> ASTReader::getSourceDescriptor(unsigned ID) { - if (const Module *M = getSubmodule(ID)) - return ExternalASTSource::ASTSourceDescriptor(*M); + if (Module *M = getSubmodule(ID)) + return ASTSourceDescriptor(*M); // If there is only a single PCH, return it instead. // Chained PCH are not supported. @@ -8495,8 +8637,8 @@ ASTReader::getSourceDescriptor(unsigned ID) { ModuleFile &MF = ModuleMgr.getPrimaryModule(); StringRef ModuleName = llvm::sys::path::filename(MF.OriginalSourceFileName); StringRef FileName = llvm::sys::path::filename(MF.FileName); - return ASTReader::ASTSourceDescriptor(ModuleName, MF.OriginalDir, FileName, - MF.Signature); + return ASTSourceDescriptor(ModuleName, MF.OriginalDir, FileName, + MF.Signature); } return None; } @@ -9440,6 +9582,446 @@ void ASTReader::diagnoseOdrViolations() { return Hash.CalculateHash(); }; + // Used with err_module_odr_violation_mismatch_decl and + // note_module_odr_violation_mismatch_decl + // This list should be the same Decl's as in ODRHash::isDeclToBeProcessed + enum ODRMismatchDecl { + EndOfClass, + PublicSpecifer, + PrivateSpecifer, + ProtectedSpecifer, + StaticAssert, + Field, + CXXMethod, + TypeAlias, + TypeDef, + Var, + Friend, + FunctionTemplate, + Other + }; + + // Used with err_module_odr_violation_mismatch_decl_diff and + // note_module_odr_violation_mismatch_decl_diff + enum ODRMismatchDeclDifference { + StaticAssertCondition, + StaticAssertMessage, + StaticAssertOnlyMessage, + FieldName, + FieldTypeName, + FieldSingleBitField, + FieldDifferentWidthBitField, + FieldSingleMutable, + FieldSingleInitializer, + FieldDifferentInitializers, + MethodName, + MethodDeleted, + MethodDefaulted, + MethodVirtual, + MethodStatic, + MethodVolatile, + MethodConst, + MethodInline, + MethodNumberParameters, + MethodParameterType, + MethodParameterName, + MethodParameterSingleDefaultArgument, + MethodParameterDifferentDefaultArgument, + MethodNoTemplateArguments, + MethodDifferentNumberTemplateArguments, + MethodDifferentTemplateArgument, + MethodSingleBody, + MethodDifferentBody, + TypedefName, + TypedefType, + VarName, + VarType, + VarSingleInitializer, + VarDifferentInitializer, + VarConstexpr, + FriendTypeFunction, + FriendType, + FriendFunction, + FunctionTemplateDifferentNumberParameters, + FunctionTemplateParameterDifferentKind, + FunctionTemplateParameterName, + FunctionTemplateParameterSingleDefaultArgument, + FunctionTemplateParameterDifferentDefaultArgument, + FunctionTemplateParameterDifferentType, + FunctionTemplatePackParameter, + }; + + // These lambdas have the common portions of the ODR diagnostics. This + // has the same return as Diag(), so addition parameters can be passed + // in with operator<< + auto ODRDiagDeclError = [this](NamedDecl *FirstRecord, StringRef FirstModule, + SourceLocation Loc, SourceRange Range, + ODRMismatchDeclDifference DiffType) { + return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_diff) + << FirstRecord << FirstModule.empty() << FirstModule << Range + << DiffType; + }; + auto ODRDiagDeclNote = [this](StringRef SecondModule, SourceLocation Loc, + SourceRange Range, ODRMismatchDeclDifference DiffType) { + return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_diff) + << SecondModule << Range << DiffType; + }; + + auto ODRDiagField = [this, &ODRDiagDeclError, &ODRDiagDeclNote, + &ComputeQualTypeODRHash, &ComputeODRHash]( + NamedDecl *FirstRecord, StringRef FirstModule, + StringRef SecondModule, FieldDecl *FirstField, + FieldDecl *SecondField) { + IdentifierInfo *FirstII = FirstField->getIdentifier(); + IdentifierInfo *SecondII = SecondField->getIdentifier(); + if (FirstII->getName() != SecondII->getName()) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldName) + << FirstII; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldName) + << SecondII; + + return true; + } + + assert(getContext().hasSameType(FirstField->getType(), + SecondField->getType())); + + QualType FirstType = FirstField->getType(); + QualType SecondType = SecondField->getType(); + if (ComputeQualTypeODRHash(FirstType) != + ComputeQualTypeODRHash(SecondType)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldTypeName) + << FirstII << FirstType; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldTypeName) + << SecondII << SecondType; + + return true; + } + + const bool IsFirstBitField = FirstField->isBitField(); + const bool IsSecondBitField = SecondField->isBitField(); + if (IsFirstBitField != IsSecondBitField) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldSingleBitField) + << FirstII << IsFirstBitField; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldSingleBitField) + << SecondII << IsSecondBitField; + return true; + } + + if (IsFirstBitField && IsSecondBitField) { + unsigned FirstBitWidthHash = + ComputeODRHash(FirstField->getBitWidth()); + unsigned SecondBitWidthHash = + ComputeODRHash(SecondField->getBitWidth()); + if (FirstBitWidthHash != SecondBitWidthHash) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), + FieldDifferentWidthBitField) + << FirstII << FirstField->getBitWidth()->getSourceRange(); + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), + FieldDifferentWidthBitField) + << SecondII << SecondField->getBitWidth()->getSourceRange(); + return true; + } + } + + if (!PP.getLangOpts().CPlusPlus) + return false; + + const bool IsFirstMutable = FirstField->isMutable(); + const bool IsSecondMutable = SecondField->isMutable(); + if (IsFirstMutable != IsSecondMutable) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldSingleMutable) + << FirstII << IsFirstMutable; + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldSingleMutable) + << SecondII << IsSecondMutable; + return true; + } + + const Expr *FirstInitializer = FirstField->getInClassInitializer(); + const Expr *SecondInitializer = SecondField->getInClassInitializer(); + if ((!FirstInitializer && SecondInitializer) || + (FirstInitializer && !SecondInitializer)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), FieldSingleInitializer) + << FirstII << (FirstInitializer != nullptr); + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), FieldSingleInitializer) + << SecondII << (SecondInitializer != nullptr); + return true; + } + + if (FirstInitializer && SecondInitializer) { + unsigned FirstInitHash = ComputeODRHash(FirstInitializer); + unsigned SecondInitHash = ComputeODRHash(SecondInitializer); + if (FirstInitHash != SecondInitHash) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(), + FirstField->getSourceRange(), + FieldDifferentInitializers) + << FirstII << FirstInitializer->getSourceRange(); + ODRDiagDeclNote(SecondModule, SecondField->getLocation(), + SecondField->getSourceRange(), + FieldDifferentInitializers) + << SecondII << SecondInitializer->getSourceRange(); + return true; + } + } + + return false; + }; + + auto ODRDiagTypeDefOrAlias = + [&ODRDiagDeclError, &ODRDiagDeclNote, &ComputeQualTypeODRHash]( + NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule, + TypedefNameDecl *FirstTD, TypedefNameDecl *SecondTD, + bool IsTypeAlias) { + auto FirstName = FirstTD->getDeclName(); + auto SecondName = SecondTD->getDeclName(); + if (FirstName != SecondName) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstTD->getLocation(), + FirstTD->getSourceRange(), TypedefName) + << IsTypeAlias << FirstName; + ODRDiagDeclNote(SecondModule, SecondTD->getLocation(), + SecondTD->getSourceRange(), TypedefName) + << IsTypeAlias << SecondName; + return true; + } + + QualType FirstType = FirstTD->getUnderlyingType(); + QualType SecondType = SecondTD->getUnderlyingType(); + if (ComputeQualTypeODRHash(FirstType) != + ComputeQualTypeODRHash(SecondType)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstTD->getLocation(), + FirstTD->getSourceRange(), TypedefType) + << IsTypeAlias << FirstName << FirstType; + ODRDiagDeclNote(SecondModule, SecondTD->getLocation(), + SecondTD->getSourceRange(), TypedefType) + << IsTypeAlias << SecondName << SecondType; + return true; + } + + return false; + }; + + auto ODRDiagVar = [&ODRDiagDeclError, &ODRDiagDeclNote, + &ComputeQualTypeODRHash, &ComputeODRHash, + this](NamedDecl *FirstRecord, StringRef FirstModule, + StringRef SecondModule, VarDecl *FirstVD, + VarDecl *SecondVD) { + auto FirstName = FirstVD->getDeclName(); + auto SecondName = SecondVD->getDeclName(); + if (FirstName != SecondName) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarName) + << FirstName; + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarName) + << SecondName; + return true; + } + + QualType FirstType = FirstVD->getType(); + QualType SecondType = SecondVD->getType(); + if (ComputeQualTypeODRHash(FirstType) != + ComputeQualTypeODRHash(SecondType)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarType) + << FirstName << FirstType; + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarType) + << SecondName << SecondType; + return true; + } + + if (!PP.getLangOpts().CPlusPlus) + return false; + + const Expr *FirstInit = FirstVD->getInit(); + const Expr *SecondInit = SecondVD->getInit(); + if ((FirstInit == nullptr) != (SecondInit == nullptr)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarSingleInitializer) + << FirstName << (FirstInit == nullptr) + << (FirstInit ? FirstInit->getSourceRange() : SourceRange()); + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarSingleInitializer) + << SecondName << (SecondInit == nullptr) + << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); + return true; + } + + if (FirstInit && SecondInit && + ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarDifferentInitializer) + << FirstName << FirstInit->getSourceRange(); + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarDifferentInitializer) + << SecondName << SecondInit->getSourceRange(); + return true; + } + + const bool FirstIsConstexpr = FirstVD->isConstexpr(); + const bool SecondIsConstexpr = SecondVD->isConstexpr(); + if (FirstIsConstexpr != SecondIsConstexpr) { + ODRDiagDeclError(FirstRecord, FirstModule, FirstVD->getLocation(), + FirstVD->getSourceRange(), VarConstexpr) + << FirstName << FirstIsConstexpr; + ODRDiagDeclNote(SecondModule, SecondVD->getLocation(), + SecondVD->getSourceRange(), VarConstexpr) + << SecondName << SecondIsConstexpr; + return true; + } + return false; + }; + + auto DifferenceSelector = [](Decl *D) { + assert(D && "valid Decl required"); + switch (D->getKind()) { + default: + return Other; + case Decl::AccessSpec: + switch (D->getAccess()) { + case AS_public: + return PublicSpecifer; + case AS_private: + return PrivateSpecifer; + case AS_protected: + return ProtectedSpecifer; + case AS_none: + break; + } + llvm_unreachable("Invalid access specifier"); + case Decl::StaticAssert: + return StaticAssert; + case Decl::Field: + return Field; + case Decl::CXXMethod: + case Decl::CXXConstructor: + case Decl::CXXDestructor: + return CXXMethod; + case Decl::TypeAlias: + return TypeAlias; + case Decl::Typedef: + return TypeDef; + case Decl::Var: + return Var; + case Decl::Friend: + return Friend; + case Decl::FunctionTemplate: + return FunctionTemplate; + } + }; + + using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>; + auto PopulateHashes = [&ComputeSubDeclODRHash](DeclHashes &Hashes, + RecordDecl *Record, + const DeclContext *DC) { + for (auto *D : Record->decls()) { + if (!ODRHash::isDeclToBeProcessed(D, DC)) + continue; + Hashes.emplace_back(D, ComputeSubDeclODRHash(D)); + } + }; + + struct DiffResult { + Decl *FirstDecl = nullptr, *SecondDecl = nullptr; + ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other; + }; + + // If there is a diagnoseable difference, FirstDiffType and + // SecondDiffType will not be Other and FirstDecl and SecondDecl will be + // filled in if not EndOfClass. + auto FindTypeDiffs = [&DifferenceSelector](DeclHashes &FirstHashes, + DeclHashes &SecondHashes) { + DiffResult DR; + auto FirstIt = FirstHashes.begin(); + auto SecondIt = SecondHashes.begin(); + while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) { + if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() && + FirstIt->second == SecondIt->second) { + ++FirstIt; + ++SecondIt; + continue; + } + + DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first; + DR.SecondDecl = + SecondIt == SecondHashes.end() ? nullptr : SecondIt->first; + + DR.FirstDiffType = + DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass; + DR.SecondDiffType = + DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass; + return DR; + } + return DR; + }; + + // Use this to diagnose that an unexpected Decl was encountered + // or no difference was detected. This causes a generic error + // message to be emitted. + auto DiagnoseODRUnexpected = [this](DiffResult &DR, NamedDecl *FirstRecord, + StringRef FirstModule, + NamedDecl *SecondRecord, + StringRef SecondModule) { + Diag(FirstRecord->getLocation(), + diag::err_module_odr_violation_different_definitions) + << FirstRecord << FirstModule.empty() << FirstModule; + + if (DR.FirstDecl) { + Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference) + << FirstRecord << DR.FirstDecl->getSourceRange(); + } + + Diag(SecondRecord->getLocation(), + diag::note_module_odr_violation_different_definitions) + << SecondModule; + + if (DR.SecondDecl) { + Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference) + << DR.SecondDecl->getSourceRange(); + } + }; + + auto DiagnoseODRMismatch = + [this](DiffResult &DR, NamedDecl *FirstRecord, StringRef FirstModule, + NamedDecl *SecondRecord, StringRef SecondModule) { + SourceLocation FirstLoc; + SourceRange FirstRange; + auto *FirstTag = dyn_cast<TagDecl>(FirstRecord); + if (DR.FirstDiffType == EndOfClass && FirstTag) { + FirstLoc = FirstTag->getBraceRange().getEnd(); + } else { + FirstLoc = DR.FirstDecl->getLocation(); + FirstRange = DR.FirstDecl->getSourceRange(); + } + Diag(FirstLoc, diag::err_module_odr_violation_mismatch_decl) + << FirstRecord << FirstModule.empty() << FirstModule << FirstRange + << DR.FirstDiffType; + + SourceLocation SecondLoc; + SourceRange SecondRange; + auto *SecondTag = dyn_cast<TagDecl>(SecondRecord); + if (DR.SecondDiffType == EndOfClass && SecondTag) { + SecondLoc = SecondTag->getBraceRange().getEnd(); + } else { + SecondLoc = DR.SecondDecl->getLocation(); + SecondRange = DR.SecondDecl->getSourceRange(); + } + Diag(SecondLoc, diag::note_module_odr_violation_mismatch_decl) + << SecondModule << SecondRange << DR.SecondDiffType; + }; + // Issue any pending ODR-failure diagnostics. for (auto &Merge : OdrMergeFailures) { // If we've already pointed out a specific problem with this class, don't @@ -9473,16 +10055,16 @@ void ASTReader::diagnoseOdrViolations() { BaseVirtual, BaseAccess, }; - auto ODRDiagError = [FirstRecord, &FirstModule, - this](SourceLocation Loc, SourceRange Range, - ODRDefinitionDataDifference DiffType) { + auto ODRDiagBaseError = [FirstRecord, &FirstModule, + this](SourceLocation Loc, SourceRange Range, + ODRDefinitionDataDifference DiffType) { return Diag(Loc, diag::err_module_odr_violation_definition_data) << FirstRecord << FirstModule.empty() << FirstModule << Range << DiffType; }; - auto ODRDiagNote = [&SecondModule, - this](SourceLocation Loc, SourceRange Range, - ODRDefinitionDataDifference DiffType) { + auto ODRDiagBaseNote = [&SecondModule, + this](SourceLocation Loc, SourceRange Range, + ODRDefinitionDataDifference DiffType) { return Diag(Loc, diag::note_module_odr_violation_definition_data) << SecondModule << Range << DiffType; }; @@ -9501,22 +10083,22 @@ void ASTReader::diagnoseOdrViolations() { }; if (FirstNumBases != SecondNumBases) { - ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD), - NumBases) + ODRDiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD), + NumBases) << FirstNumBases; - ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), - NumBases) + ODRDiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), + NumBases) << SecondNumBases; Diagnosed = true; break; } if (FirstNumVBases != SecondNumVBases) { - ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD), - NumVBases) + ODRDiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD), + NumVBases) << FirstNumVBases; - ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), - NumVBases) + ODRDiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD), + NumVBases) << SecondNumVBases; Diagnosed = true; break; @@ -9530,33 +10112,33 @@ void ASTReader::diagnoseOdrViolations() { auto SecondBase = SecondBases[i]; if (ComputeQualTypeODRHash(FirstBase.getType()) != ComputeQualTypeODRHash(SecondBase.getType())) { - ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(), - BaseType) + ODRDiagBaseError(FirstRecord->getLocation(), + FirstBase.getSourceRange(), BaseType) << (i + 1) << FirstBase.getType(); - ODRDiagNote(SecondRecord->getLocation(), - SecondBase.getSourceRange(), BaseType) + ODRDiagBaseNote(SecondRecord->getLocation(), + SecondBase.getSourceRange(), BaseType) << (i + 1) << SecondBase.getType(); break; } if (FirstBase.isVirtual() != SecondBase.isVirtual()) { - ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(), - BaseVirtual) + ODRDiagBaseError(FirstRecord->getLocation(), + FirstBase.getSourceRange(), BaseVirtual) << (i + 1) << FirstBase.isVirtual() << FirstBase.getType(); - ODRDiagNote(SecondRecord->getLocation(), - SecondBase.getSourceRange(), BaseVirtual) + ODRDiagBaseNote(SecondRecord->getLocation(), + SecondBase.getSourceRange(), BaseVirtual) << (i + 1) << SecondBase.isVirtual() << SecondBase.getType(); break; } if (FirstBase.getAccessSpecifierAsWritten() != SecondBase.getAccessSpecifierAsWritten()) { - ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(), - BaseAccess) + ODRDiagBaseError(FirstRecord->getLocation(), + FirstBase.getSourceRange(), BaseAccess) << (i + 1) << FirstBase.getType() << (int)FirstBase.getAccessSpecifierAsWritten(); - ODRDiagNote(SecondRecord->getLocation(), - SecondBase.getSourceRange(), BaseAccess) + ODRDiagBaseNote(SecondRecord->getLocation(), + SecondBase.getSourceRange(), BaseAccess) << (i + 1) << SecondBase.getType() << (int)SecondBase.getAccessSpecifierAsWritten(); break; @@ -9569,8 +10151,6 @@ void ASTReader::diagnoseOdrViolations() { } } - using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>; - const ClassTemplateDecl *FirstTemplate = FirstRecord->getDescribedClassTemplate(); const ClassTemplateDecl *SecondTemplate = @@ -9611,16 +10191,16 @@ void ASTReader::diagnoseOdrViolations() { if (FirstIt->second == SecondIt->second) continue; - auto ODRDiagError = [FirstRecord, &FirstModule, - this](SourceLocation Loc, SourceRange Range, - ODRTemplateDifference DiffType) { + auto ODRDiagTemplateError = [FirstRecord, &FirstModule, this]( + SourceLocation Loc, SourceRange Range, + ODRTemplateDifference DiffType) { return Diag(Loc, diag::err_module_odr_violation_template_parameter) << FirstRecord << FirstModule.empty() << FirstModule << Range << DiffType; }; - auto ODRDiagNote = [&SecondModule, - this](SourceLocation Loc, SourceRange Range, - ODRTemplateDifference DiffType) { + auto ODRDiagTemplateNote = [&SecondModule, this]( + SourceLocation Loc, SourceRange Range, + ODRTemplateDifference DiffType) { return Diag(Loc, diag::note_module_odr_violation_template_parameter) << SecondModule << Range << DiffType; }; @@ -9641,11 +10221,13 @@ void ASTReader::diagnoseOdrViolations() { SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo(); assert((!FirstNameEmpty || !SecondNameEmpty) && "Both template parameters cannot be unnamed."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - FirstNameEmpty ? ParamEmptyName : ParamName) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + FirstNameEmpty ? ParamEmptyName : ParamName) << FirstName; - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - SecondNameEmpty ? ParamEmptyName : ParamName) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + SecondNameEmpty ? ParamEmptyName : ParamName) << SecondName; break; } @@ -9664,13 +10246,13 @@ void ASTReader::diagnoseOdrViolations() { !SecondParam->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstDecl->getLocation(), - FirstDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasFirstDefaultArgument; - ODRDiagNote(SecondDecl->getLocation(), - SecondDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasSecondDefaultArgument; break; } @@ -9678,10 +10260,12 @@ void ASTReader::diagnoseOdrViolations() { assert(HasFirstDefaultArgument && HasSecondDefaultArgument && "Expecting default arguments."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - ParamDifferentDefaultArgument); - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - ParamDifferentDefaultArgument); + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamDifferentDefaultArgument); + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamDifferentDefaultArgument); break; } @@ -9696,13 +10280,13 @@ void ASTReader::diagnoseOdrViolations() { !SecondParam->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstDecl->getLocation(), - FirstDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasFirstDefaultArgument; - ODRDiagNote(SecondDecl->getLocation(), - SecondDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasSecondDefaultArgument; break; } @@ -9710,10 +10294,12 @@ void ASTReader::diagnoseOdrViolations() { assert(HasFirstDefaultArgument && HasSecondDefaultArgument && "Expecting default arguments."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - ParamDifferentDefaultArgument); - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - ParamDifferentDefaultArgument); + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamDifferentDefaultArgument); + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamDifferentDefaultArgument); break; } @@ -9729,13 +10315,13 @@ void ASTReader::diagnoseOdrViolations() { !SecondParam->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstDecl->getLocation(), - FirstDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasFirstDefaultArgument; - ODRDiagNote(SecondDecl->getLocation(), - SecondDecl->getSourceRange(), - ParamSingleDefaultArgument) + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamSingleDefaultArgument) << HasSecondDefaultArgument; break; } @@ -9743,10 +10329,12 @@ void ASTReader::diagnoseOdrViolations() { assert(HasFirstDefaultArgument && HasSecondDefaultArgument && "Expecting default arguments."); - ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(), - ParamDifferentDefaultArgument); - ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(), - ParamDifferentDefaultArgument); + ODRDiagTemplateError(FirstDecl->getLocation(), + FirstDecl->getSourceRange(), + ParamDifferentDefaultArgument); + ODRDiagTemplateNote(SecondDecl->getLocation(), + SecondDecl->getSourceRange(), + ParamDifferentDefaultArgument); break; } @@ -9763,224 +10351,32 @@ void ASTReader::diagnoseOdrViolations() { DeclHashes FirstHashes; DeclHashes SecondHashes; + const DeclContext *DC = FirstRecord; + PopulateHashes(FirstHashes, FirstRecord, DC); + PopulateHashes(SecondHashes, SecondRecord, DC); - auto PopulateHashes = [&ComputeSubDeclODRHash, FirstRecord]( - DeclHashes &Hashes, CXXRecordDecl *Record) { - for (auto *D : Record->decls()) { - // Due to decl merging, the first CXXRecordDecl is the parent of - // Decls in both records. - if (!ODRHash::isWhitelistedDecl(D, FirstRecord)) - continue; - Hashes.emplace_back(D, ComputeSubDeclODRHash(D)); - } - }; - PopulateHashes(FirstHashes, FirstRecord); - PopulateHashes(SecondHashes, SecondRecord); - - // Used with err_module_odr_violation_mismatch_decl and - // note_module_odr_violation_mismatch_decl - // This list should be the same Decl's as in ODRHash::isWhiteListedDecl - enum { - EndOfClass, - PublicSpecifer, - PrivateSpecifer, - ProtectedSpecifer, - StaticAssert, - Field, - CXXMethod, - TypeAlias, - TypeDef, - Var, - Friend, - FunctionTemplate, - Other - } FirstDiffType = Other, - SecondDiffType = Other; - - auto DifferenceSelector = [](Decl *D) { - assert(D && "valid Decl required"); - switch (D->getKind()) { - default: - return Other; - case Decl::AccessSpec: - switch (D->getAccess()) { - case AS_public: - return PublicSpecifer; - case AS_private: - return PrivateSpecifer; - case AS_protected: - return ProtectedSpecifer; - case AS_none: - break; - } - llvm_unreachable("Invalid access specifier"); - case Decl::StaticAssert: - return StaticAssert; - case Decl::Field: - return Field; - case Decl::CXXMethod: - case Decl::CXXConstructor: - case Decl::CXXDestructor: - return CXXMethod; - case Decl::TypeAlias: - return TypeAlias; - case Decl::Typedef: - return TypeDef; - case Decl::Var: - return Var; - case Decl::Friend: - return Friend; - case Decl::FunctionTemplate: - return FunctionTemplate; - } - }; - - Decl *FirstDecl = nullptr; - Decl *SecondDecl = nullptr; - auto FirstIt = FirstHashes.begin(); - auto SecondIt = SecondHashes.begin(); - - // If there is a diagnoseable difference, FirstDiffType and - // SecondDiffType will not be Other and FirstDecl and SecondDecl will be - // filled in if not EndOfClass. - while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) { - if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() && - FirstIt->second == SecondIt->second) { - ++FirstIt; - ++SecondIt; - continue; - } - - FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first; - SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first; - - FirstDiffType = FirstDecl ? DifferenceSelector(FirstDecl) : EndOfClass; - SecondDiffType = - SecondDecl ? DifferenceSelector(SecondDecl) : EndOfClass; - - break; - } + auto DR = FindTypeDiffs(FirstHashes, SecondHashes); + ODRMismatchDecl FirstDiffType = DR.FirstDiffType; + ODRMismatchDecl SecondDiffType = DR.SecondDiffType; + Decl *FirstDecl = DR.FirstDecl; + Decl *SecondDecl = DR.SecondDecl; if (FirstDiffType == Other || SecondDiffType == Other) { - // Reaching this point means an unexpected Decl was encountered - // or no difference was detected. This causes a generic error - // message to be emitted. - Diag(FirstRecord->getLocation(), - diag::err_module_odr_violation_different_definitions) - << FirstRecord << FirstModule.empty() << FirstModule; - - if (FirstDecl) { - Diag(FirstDecl->getLocation(), diag::note_first_module_difference) - << FirstRecord << FirstDecl->getSourceRange(); - } - - Diag(SecondRecord->getLocation(), - diag::note_module_odr_violation_different_definitions) - << SecondModule; - - if (SecondDecl) { - Diag(SecondDecl->getLocation(), diag::note_second_module_difference) - << SecondDecl->getSourceRange(); - } - + DiagnoseODRUnexpected(DR, FirstRecord, FirstModule, SecondRecord, + SecondModule); Diagnosed = true; break; } if (FirstDiffType != SecondDiffType) { - SourceLocation FirstLoc; - SourceRange FirstRange; - if (FirstDiffType == EndOfClass) { - FirstLoc = FirstRecord->getBraceRange().getEnd(); - } else { - FirstLoc = FirstIt->first->getLocation(); - FirstRange = FirstIt->first->getSourceRange(); - } - Diag(FirstLoc, diag::err_module_odr_violation_mismatch_decl) - << FirstRecord << FirstModule.empty() << FirstModule << FirstRange - << FirstDiffType; - - SourceLocation SecondLoc; - SourceRange SecondRange; - if (SecondDiffType == EndOfClass) { - SecondLoc = SecondRecord->getBraceRange().getEnd(); - } else { - SecondLoc = SecondDecl->getLocation(); - SecondRange = SecondDecl->getSourceRange(); - } - Diag(SecondLoc, diag::note_module_odr_violation_mismatch_decl) - << SecondModule << SecondRange << SecondDiffType; + DiagnoseODRMismatch(DR, FirstRecord, FirstModule, SecondRecord, + SecondModule); Diagnosed = true; break; } assert(FirstDiffType == SecondDiffType); - // Used with err_module_odr_violation_mismatch_decl_diff and - // note_module_odr_violation_mismatch_decl_diff - enum ODRDeclDifference { - StaticAssertCondition, - StaticAssertMessage, - StaticAssertOnlyMessage, - FieldName, - FieldTypeName, - FieldSingleBitField, - FieldDifferentWidthBitField, - FieldSingleMutable, - FieldSingleInitializer, - FieldDifferentInitializers, - MethodName, - MethodDeleted, - MethodDefaulted, - MethodVirtual, - MethodStatic, - MethodVolatile, - MethodConst, - MethodInline, - MethodNumberParameters, - MethodParameterType, - MethodParameterName, - MethodParameterSingleDefaultArgument, - MethodParameterDifferentDefaultArgument, - MethodNoTemplateArguments, - MethodDifferentNumberTemplateArguments, - MethodDifferentTemplateArgument, - MethodSingleBody, - MethodDifferentBody, - TypedefName, - TypedefType, - VarName, - VarType, - VarSingleInitializer, - VarDifferentInitializer, - VarConstexpr, - FriendTypeFunction, - FriendType, - FriendFunction, - FunctionTemplateDifferentNumberParameters, - FunctionTemplateParameterDifferentKind, - FunctionTemplateParameterName, - FunctionTemplateParameterSingleDefaultArgument, - FunctionTemplateParameterDifferentDefaultArgument, - FunctionTemplateParameterDifferentType, - FunctionTemplatePackParameter, - }; - - // These lambdas have the common portions of the ODR diagnostics. This - // has the same return as Diag(), so addition parameters can be passed - // in with operator<< - auto ODRDiagError = [FirstRecord, &FirstModule, this]( - SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) { - return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_diff) - << FirstRecord << FirstModule.empty() << FirstModule << Range - << DiffType; - }; - auto ODRDiagNote = [&SecondModule, this]( - SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) { - return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_diff) - << SecondModule << Range << DiffType; - }; - switch (FirstDiffType) { case Other: case EndOfClass: @@ -9998,10 +10394,10 @@ void ASTReader::diagnoseOdrViolations() { unsigned FirstODRHash = ComputeODRHash(FirstExpr); unsigned SecondODRHash = ComputeODRHash(SecondExpr); if (FirstODRHash != SecondODRHash) { - ODRDiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(), - StaticAssertCondition); - ODRDiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(), - StaticAssertCondition); + ODRDiagDeclError(FirstRecord, FirstModule, FirstExpr->getBeginLoc(), + FirstExpr->getSourceRange(), StaticAssertCondition); + ODRDiagDeclNote(SecondModule, SecondExpr->getBeginLoc(), + SecondExpr->getSourceRange(), StaticAssertCondition); Diagnosed = true; break; } @@ -10026,9 +10422,11 @@ void ASTReader::diagnoseOdrViolations() { SecondLoc = SecondSA->getBeginLoc(); SecondRange = SecondSA->getSourceRange(); } - ODRDiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage) + ODRDiagDeclError(FirstRecord, FirstModule, FirstLoc, FirstRange, + StaticAssertOnlyMessage) << (FirstStr == nullptr); - ODRDiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage) + ODRDiagDeclNote(SecondModule, SecondLoc, SecondRange, + StaticAssertOnlyMessage) << (SecondStr == nullptr); Diagnosed = true; break; @@ -10036,126 +10434,19 @@ void ASTReader::diagnoseOdrViolations() { if (FirstStr && SecondStr && FirstStr->getString() != SecondStr->getString()) { - ODRDiagError(FirstStr->getBeginLoc(), FirstStr->getSourceRange(), - StaticAssertMessage); - ODRDiagNote(SecondStr->getBeginLoc(), SecondStr->getSourceRange(), - StaticAssertMessage); + ODRDiagDeclError(FirstRecord, FirstModule, FirstStr->getBeginLoc(), + FirstStr->getSourceRange(), StaticAssertMessage); + ODRDiagDeclNote(SecondModule, SecondStr->getBeginLoc(), + SecondStr->getSourceRange(), StaticAssertMessage); Diagnosed = true; break; } break; } case Field: { - FieldDecl *FirstField = cast<FieldDecl>(FirstDecl); - FieldDecl *SecondField = cast<FieldDecl>(SecondDecl); - IdentifierInfo *FirstII = FirstField->getIdentifier(); - IdentifierInfo *SecondII = SecondField->getIdentifier(); - if (FirstII->getName() != SecondII->getName()) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldName) - << FirstII; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldName) - << SecondII; - - Diagnosed = true; - break; - } - - assert(getContext().hasSameType(FirstField->getType(), - SecondField->getType())); - - QualType FirstType = FirstField->getType(); - QualType SecondType = SecondField->getType(); - if (ComputeQualTypeODRHash(FirstType) != - ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldTypeName) - << FirstII << FirstType; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldTypeName) - << SecondII << SecondType; - - Diagnosed = true; - break; - } - - const bool IsFirstBitField = FirstField->isBitField(); - const bool IsSecondBitField = SecondField->isBitField(); - if (IsFirstBitField != IsSecondBitField) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldSingleBitField) - << FirstII << IsFirstBitField; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldSingleBitField) - << SecondII << IsSecondBitField; - Diagnosed = true; - break; - } - - if (IsFirstBitField && IsSecondBitField) { - unsigned FirstBitWidthHash = - ComputeODRHash(FirstField->getBitWidth()); - unsigned SecondBitWidthHash = - ComputeODRHash(SecondField->getBitWidth()); - if (FirstBitWidthHash != SecondBitWidthHash) { - ODRDiagError(FirstField->getLocation(), - FirstField->getSourceRange(), - FieldDifferentWidthBitField) - << FirstII << FirstField->getBitWidth()->getSourceRange(); - ODRDiagNote(SecondField->getLocation(), - SecondField->getSourceRange(), - FieldDifferentWidthBitField) - << SecondII << SecondField->getBitWidth()->getSourceRange(); - Diagnosed = true; - break; - } - } - - const bool IsFirstMutable = FirstField->isMutable(); - const bool IsSecondMutable = SecondField->isMutable(); - if (IsFirstMutable != IsSecondMutable) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldSingleMutable) - << FirstII << IsFirstMutable; - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldSingleMutable) - << SecondII << IsSecondMutable; - Diagnosed = true; - break; - } - - const Expr *FirstInitializer = FirstField->getInClassInitializer(); - const Expr *SecondInitializer = SecondField->getInClassInitializer(); - if ((!FirstInitializer && SecondInitializer) || - (FirstInitializer && !SecondInitializer)) { - ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), - FieldSingleInitializer) - << FirstII << (FirstInitializer != nullptr); - ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(), - FieldSingleInitializer) - << SecondII << (SecondInitializer != nullptr); - Diagnosed = true; - break; - } - - if (FirstInitializer && SecondInitializer) { - unsigned FirstInitHash = ComputeODRHash(FirstInitializer); - unsigned SecondInitHash = ComputeODRHash(SecondInitializer); - if (FirstInitHash != SecondInitHash) { - ODRDiagError(FirstField->getLocation(), - FirstField->getSourceRange(), - FieldDifferentInitializers) - << FirstII << FirstInitializer->getSourceRange(); - ODRDiagNote(SecondField->getLocation(), - SecondField->getSourceRange(), - FieldDifferentInitializers) - << SecondII << SecondInitializer->getSourceRange(); - Diagnosed = true; - break; - } - } - + Diagnosed = ODRDiagField(FirstRecord, FirstModule, SecondModule, + cast<FieldDecl>(FirstDecl), + cast<FieldDecl>(SecondDecl)); break; } case CXXMethod: { @@ -10177,11 +10468,11 @@ void ASTReader::diagnoseOdrViolations() { auto FirstName = FirstMethod->getDeclName(); auto SecondName = SecondMethod->getDeclName(); if (FirstMethodType != SecondMethodType || FirstName != SecondName) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodName) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodName) << FirstMethodType << FirstName; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodName) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodName) << SecondMethodType << SecondName; Diagnosed = true; @@ -10191,12 +10482,12 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstDeleted = FirstMethod->isDeletedAsWritten(); const bool SecondDeleted = SecondMethod->isDeletedAsWritten(); if (FirstDeleted != SecondDeleted) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodDeleted) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDeleted) << FirstMethodType << FirstName << FirstDeleted; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodDeleted) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodDeleted) << SecondMethodType << SecondName << SecondDeleted; Diagnosed = true; break; @@ -10205,12 +10496,12 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted(); const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted(); if (FirstDefaulted != SecondDefaulted) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodDefaulted) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDefaulted) << FirstMethodType << FirstName << FirstDefaulted; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodDefaulted) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodDefaulted) << SecondMethodType << SecondName << SecondDefaulted; Diagnosed = true; break; @@ -10222,11 +10513,11 @@ void ASTReader::diagnoseOdrViolations() { const bool SecondPure = SecondMethod->isPure(); if ((FirstVirtual || SecondVirtual) && (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodVirtual) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodVirtual) << FirstMethodType << FirstName << FirstPure << FirstVirtual; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodVirtual) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodVirtual) << SecondMethodType << SecondName << SecondPure << SecondVirtual; Diagnosed = true; break; @@ -10240,11 +10531,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstStatic = FirstStorage == SC_Static; const bool SecondStatic = SecondStorage == SC_Static; if (FirstStatic != SecondStatic) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodStatic) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodStatic) << FirstMethodType << FirstName << FirstStatic; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodStatic) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodStatic) << SecondMethodType << SecondName << SecondStatic; Diagnosed = true; break; @@ -10253,11 +10544,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstVolatile = FirstMethod->isVolatile(); const bool SecondVolatile = SecondMethod->isVolatile(); if (FirstVolatile != SecondVolatile) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodVolatile) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodVolatile) << FirstMethodType << FirstName << FirstVolatile; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodVolatile) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodVolatile) << SecondMethodType << SecondName << SecondVolatile; Diagnosed = true; break; @@ -10266,11 +10557,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstConst = FirstMethod->isConst(); const bool SecondConst = SecondMethod->isConst(); if (FirstConst != SecondConst) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodConst) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodConst) << FirstMethodType << FirstName << FirstConst; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodConst) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodConst) << SecondMethodType << SecondName << SecondConst; Diagnosed = true; break; @@ -10279,11 +10570,11 @@ void ASTReader::diagnoseOdrViolations() { const bool FirstInline = FirstMethod->isInlineSpecified(); const bool SecondInline = SecondMethod->isInlineSpecified(); if (FirstInline != SecondInline) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodInline) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodInline) << FirstMethodType << FirstName << FirstInline; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodInline) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodInline) << SecondMethodType << SecondName << SecondInline; Diagnosed = true; break; @@ -10292,11 +10583,13 @@ void ASTReader::diagnoseOdrViolations() { const unsigned FirstNumParameters = FirstMethod->param_size(); const unsigned SecondNumParameters = SecondMethod->param_size(); if (FirstNumParameters != SecondNumParameters) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodNumberParameters) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodNumberParameters) << FirstMethodType << FirstName << FirstNumParameters; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodNumberParameters) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodNumberParameters) << SecondMethodType << SecondName << SecondNumParameters; Diagnosed = true; break; @@ -10315,27 +10608,31 @@ void ASTReader::diagnoseOdrViolations() { ComputeQualTypeODRHash(SecondParamType)) { if (const DecayedType *ParamDecayedType = FirstParamType->getAs<DecayedType>()) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodParameterType) << FirstMethodType << FirstName << (I + 1) << FirstParamType << true << ParamDecayedType->getOriginalType(); } else { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodParameterType) << FirstMethodType << FirstName << (I + 1) << FirstParamType << false; } if (const DecayedType *ParamDecayedType = SecondParamType->getAs<DecayedType>()) { - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterType) << SecondMethodType << SecondName << (I + 1) << SecondParamType << true << ParamDecayedType->getOriginalType(); } else { - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodParameterType) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterType) << SecondMethodType << SecondName << (I + 1) << SecondParamType << false; } @@ -10346,11 +10643,12 @@ void ASTReader::diagnoseOdrViolations() { DeclarationName FirstParamName = FirstParam->getDeclName(); DeclarationName SecondParamName = SecondParam->getDeclName(); if (FirstParamName != SecondParamName) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodParameterName) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodParameterName) << FirstMethodType << FirstName << (I + 1) << FirstParamName; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodParameterName) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodParameterName) << SecondMethodType << SecondName << (I + 1) << SecondParamName; ParameterMismatch = true; break; @@ -10359,15 +10657,16 @@ void ASTReader::diagnoseOdrViolations() { const Expr *FirstInit = FirstParam->getInit(); const Expr *SecondInit = SecondParam->getInit(); if ((FirstInit == nullptr) != (SecondInit == nullptr)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodParameterSingleDefaultArgument) << FirstMethodType << FirstName << (I + 1) << (FirstInit == nullptr) << (FirstInit ? FirstInit->getSourceRange() : SourceRange()); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterSingleDefaultArgument) << SecondMethodType << SecondName << (I + 1) << (SecondInit == nullptr) << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); @@ -10377,14 +10676,15 @@ void ASTReader::diagnoseOdrViolations() { if (FirstInit && SecondInit && ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodParameterDifferentDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodParameterDifferentDefaultArgument) << FirstMethodType << FirstName << (I + 1) << FirstInit->getSourceRange(); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodParameterDifferentDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodParameterDifferentDefaultArgument) << SecondMethodType << SecondName << (I + 1) << SecondInit->getSourceRange(); ParameterMismatch = true; @@ -10405,11 +10705,13 @@ void ASTReader::diagnoseOdrViolations() { if ((FirstTemplateArgs && !SecondTemplateArgs) || (!FirstTemplateArgs && SecondTemplateArgs)) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodNoTemplateArguments) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodNoTemplateArguments) << FirstMethodType << FirstName << (FirstTemplateArgs != nullptr); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodNoTemplateArguments) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodNoTemplateArguments) << SecondMethodType << SecondName << (SecondTemplateArgs != nullptr); @@ -10439,14 +10741,15 @@ void ASTReader::diagnoseOdrViolations() { ExpandTemplateArgumentList(SecondTemplateArgs); if (FirstExpandedList.size() != SecondExpandedList.size()) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodDifferentNumberTemplateArguments) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstMethod->getLocation(), + FirstMethod->getSourceRange(), + MethodDifferentNumberTemplateArguments) << FirstMethodType << FirstName << (unsigned)FirstExpandedList.size(); - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodDifferentNumberTemplateArguments) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodDifferentNumberTemplateArguments) << SecondMethodType << SecondName << (unsigned)SecondExpandedList.size(); @@ -10463,13 +10766,13 @@ void ASTReader::diagnoseOdrViolations() { continue; } - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), - MethodDifferentTemplateArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDifferentTemplateArgument) << FirstMethodType << FirstName << FirstTA << i + 1; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), - MethodDifferentTemplateArgument) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), + MethodDifferentTemplateArgument) << SecondMethodType << SecondName << SecondTA << i + 1; TemplateArgumentMismatch = true; @@ -10498,22 +10801,22 @@ void ASTReader::diagnoseOdrViolations() { ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash(); if (HasFirstBody != HasSecondBody) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodSingleBody) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodSingleBody) << FirstMethodType << FirstName << HasFirstBody; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodSingleBody) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodSingleBody) << SecondMethodType << SecondName << HasSecondBody; Diagnosed = true; break; } if (HasFirstBody && HasSecondBody) { - ODRDiagError(FirstMethod->getLocation(), - FirstMethod->getSourceRange(), MethodDifferentBody) + ODRDiagDeclError(FirstRecord, FirstModule, FirstMethod->getLocation(), + FirstMethod->getSourceRange(), MethodDifferentBody) << FirstMethodType << FirstName; - ODRDiagNote(SecondMethod->getLocation(), - SecondMethod->getSourceRange(), MethodDifferentBody) + ODRDiagDeclNote(SecondModule, SecondMethod->getLocation(), + SecondMethod->getSourceRange(), MethodDifferentBody) << SecondMethodType << SecondName; Diagnosed = true; break; @@ -10523,105 +10826,16 @@ void ASTReader::diagnoseOdrViolations() { } case TypeAlias: case TypeDef: { - TypedefNameDecl *FirstTD = cast<TypedefNameDecl>(FirstDecl); - TypedefNameDecl *SecondTD = cast<TypedefNameDecl>(SecondDecl); - auto FirstName = FirstTD->getDeclName(); - auto SecondName = SecondTD->getDeclName(); - if (FirstName != SecondName) { - ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(), - TypedefName) - << (FirstDiffType == TypeAlias) << FirstName; - ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(), - TypedefName) - << (FirstDiffType == TypeAlias) << SecondName; - Diagnosed = true; - break; - } - - QualType FirstType = FirstTD->getUnderlyingType(); - QualType SecondType = SecondTD->getUnderlyingType(); - if (ComputeQualTypeODRHash(FirstType) != - ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(), - TypedefType) - << (FirstDiffType == TypeAlias) << FirstName << FirstType; - ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(), - TypedefType) - << (FirstDiffType == TypeAlias) << SecondName << SecondType; - Diagnosed = true; - break; - } + Diagnosed = ODRDiagTypeDefOrAlias( + FirstRecord, FirstModule, SecondModule, + cast<TypedefNameDecl>(FirstDecl), cast<TypedefNameDecl>(SecondDecl), + FirstDiffType == TypeAlias); break; } case Var: { - VarDecl *FirstVD = cast<VarDecl>(FirstDecl); - VarDecl *SecondVD = cast<VarDecl>(SecondDecl); - auto FirstName = FirstVD->getDeclName(); - auto SecondName = SecondVD->getDeclName(); - if (FirstName != SecondName) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarName) - << FirstName; - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarName) - << SecondName; - Diagnosed = true; - break; - } - - QualType FirstType = FirstVD->getType(); - QualType SecondType = SecondVD->getType(); - if (ComputeQualTypeODRHash(FirstType) != - ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarType) - << FirstName << FirstType; - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarType) - << SecondName << SecondType; - Diagnosed = true; - break; - } - - const Expr *FirstInit = FirstVD->getInit(); - const Expr *SecondInit = SecondVD->getInit(); - if ((FirstInit == nullptr) != (SecondInit == nullptr)) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarSingleInitializer) - << FirstName << (FirstInit == nullptr) - << (FirstInit ? FirstInit->getSourceRange(): SourceRange()); - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarSingleInitializer) - << SecondName << (SecondInit == nullptr) - << (SecondInit ? SecondInit->getSourceRange() : SourceRange()); - Diagnosed = true; - break; - } - - if (FirstInit && SecondInit && - ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarDifferentInitializer) - << FirstName << FirstInit->getSourceRange(); - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarDifferentInitializer) - << SecondName << SecondInit->getSourceRange(); - Diagnosed = true; - break; - } - - const bool FirstIsConstexpr = FirstVD->isConstexpr(); - const bool SecondIsConstexpr = SecondVD->isConstexpr(); - if (FirstIsConstexpr != SecondIsConstexpr) { - ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(), - VarConstexpr) - << FirstName << FirstIsConstexpr; - ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(), - VarConstexpr) - << SecondName << SecondIsConstexpr; - Diagnosed = true; - break; - } + Diagnosed = + ODRDiagVar(FirstRecord, FirstModule, SecondModule, + cast<VarDecl>(FirstDecl), cast<VarDecl>(SecondDecl)); break; } case Friend: { @@ -10635,11 +10849,12 @@ void ASTReader::diagnoseOdrViolations() { TypeSourceInfo *SecondTSI = SecondFriend->getFriendType(); if (FirstND && SecondND) { - ODRDiagError(FirstFriend->getFriendLoc(), - FirstFriend->getSourceRange(), FriendFunction) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstFriend->getFriendLoc(), + FirstFriend->getSourceRange(), FriendFunction) << FirstND; - ODRDiagNote(SecondFriend->getFriendLoc(), - SecondFriend->getSourceRange(), FriendFunction) + ODRDiagDeclNote(SecondModule, SecondFriend->getFriendLoc(), + SecondFriend->getSourceRange(), FriendFunction) << SecondND; Diagnosed = true; @@ -10651,21 +10866,22 @@ void ASTReader::diagnoseOdrViolations() { QualType SecondFriendType = SecondTSI->getType(); assert(ComputeQualTypeODRHash(FirstFriendType) != ComputeQualTypeODRHash(SecondFriendType)); - ODRDiagError(FirstFriend->getFriendLoc(), - FirstFriend->getSourceRange(), FriendType) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstFriend->getFriendLoc(), + FirstFriend->getSourceRange(), FriendType) << FirstFriendType; - ODRDiagNote(SecondFriend->getFriendLoc(), - SecondFriend->getSourceRange(), FriendType) + ODRDiagDeclNote(SecondModule, SecondFriend->getFriendLoc(), + SecondFriend->getSourceRange(), FriendType) << SecondFriendType; Diagnosed = true; break; } - ODRDiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(), - FriendTypeFunction) + ODRDiagDeclError(FirstRecord, FirstModule, FirstFriend->getFriendLoc(), + FirstFriend->getSourceRange(), FriendTypeFunction) << (FirstTSI == nullptr); - ODRDiagNote(SecondFriend->getFriendLoc(), - SecondFriend->getSourceRange(), FriendTypeFunction) + ODRDiagDeclNote(SecondModule, SecondFriend->getFriendLoc(), + SecondFriend->getSourceRange(), FriendTypeFunction) << (SecondTSI == nullptr); Diagnosed = true; @@ -10683,14 +10899,15 @@ void ASTReader::diagnoseOdrViolations() { SecondTemplate->getTemplateParameters(); if (FirstTPL->size() != SecondTPL->size()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateDifferentNumberParameters) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateDifferentNumberParameters) << FirstTemplate << FirstTPL->size(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateDifferentNumberParameters) - << SecondTemplate << SecondTPL->size(); + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateDifferentNumberParameters) + << SecondTemplate << SecondTPL->size(); Diagnosed = true; break; @@ -10720,13 +10937,14 @@ void ASTReader::diagnoseOdrViolations() { } }; - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentKind) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentKind) << FirstTemplate << (i + 1) << GetParamType(FirstParam); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentKind) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentKind) << SecondTemplate << (i + 1) << GetParamType(SecondParam); ParameterMismatch = true; @@ -10734,14 +10952,14 @@ void ASTReader::diagnoseOdrViolations() { } if (FirstParam->getName() != SecondParam->getName()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterName) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), FunctionTemplateParameterName) << FirstTemplate << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterName) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterName) << SecondTemplate << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam; ParameterMismatch = true; @@ -10761,13 +10979,14 @@ void ASTReader::diagnoseOdrViolations() { SecondTTPD->hasDefaultArgument() && !SecondTTPD->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << FirstTemplate << (i + 1) << HasFirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << SecondTemplate << (i + 1) << HasSecondDefaultArgument; ParameterMismatch = true; break; @@ -10778,13 +10997,15 @@ void ASTReader::diagnoseOdrViolations() { QualType SecondType = SecondTTPD->getDefaultArgument(); if (ComputeQualTypeODRHash(FirstType) != ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << FirstTemplate << (i + 1) << FirstType; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclNote( + SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << SecondTemplate << (i + 1) << SecondType; ParameterMismatch = true; break; @@ -10793,13 +11014,14 @@ void ASTReader::diagnoseOdrViolations() { if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplatePackParameter) << FirstTemplate << (i + 1) << FirstTTPD->isParameterPack(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplatePackParameter) << SecondTemplate << (i + 1) << SecondTTPD->isParameterPack(); ParameterMismatch = true; break; @@ -10820,13 +11042,14 @@ void ASTReader::diagnoseOdrViolations() { if (ComputeTemplateParameterListODRHash(FirstTPL) != ComputeTemplateParameterListODRHash(SecondTPL)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << FirstTemplate << (i + 1); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << SecondTemplate << (i + 1); ParameterMismatch = true; break; @@ -10839,13 +11062,14 @@ void ASTReader::diagnoseOdrViolations() { SecondTTPD->hasDefaultArgument() && !SecondTTPD->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << FirstTemplate << (i + 1) << HasFirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << SecondTemplate << (i + 1) << HasSecondDefaultArgument; ParameterMismatch = true; break; @@ -10858,13 +11082,15 @@ void ASTReader::diagnoseOdrViolations() { SecondTTPD->getDefaultArgument().getArgument(); if (ComputeTemplateArgumentODRHash(FirstTA) != ComputeTemplateArgumentODRHash(SecondTA)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << FirstTemplate << (i + 1) << FirstTA; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclNote( + SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << SecondTemplate << (i + 1) << SecondTA; ParameterMismatch = true; break; @@ -10873,13 +11099,14 @@ void ASTReader::diagnoseOdrViolations() { if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplatePackParameter) << FirstTemplate << (i + 1) << FirstTTPD->isParameterPack(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplatePackParameter) << SecondTemplate << (i + 1) << SecondTTPD->isParameterPack(); ParameterMismatch = true; break; @@ -10897,13 +11124,14 @@ void ASTReader::diagnoseOdrViolations() { QualType SecondType = SecondNTTPD->getType(); if (ComputeQualTypeODRHash(FirstType) != ComputeQualTypeODRHash(SecondType)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << FirstTemplate << (i + 1); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentType) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentType) << SecondTemplate << (i + 1); ParameterMismatch = true; break; @@ -10916,13 +11144,14 @@ void ASTReader::diagnoseOdrViolations() { SecondNTTPD->hasDefaultArgument() && !SecondNTTPD->defaultArgumentWasInherited(); if (HasFirstDefaultArgument != HasSecondDefaultArgument) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << FirstTemplate << (i + 1) << HasFirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterSingleDefaultArgument) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterSingleDefaultArgument) << SecondTemplate << (i + 1) << HasSecondDefaultArgument; ParameterMismatch = true; break; @@ -10933,13 +11162,15 @@ void ASTReader::diagnoseOdrViolations() { Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument(); if (ComputeODRHash(FirstDefaultArgument) != ComputeODRHash(SecondDefaultArgument)) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclError( + FirstRecord, FirstModule, FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << FirstTemplate << (i + 1) << FirstDefaultArgument; - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplateParameterDifferentDefaultArgument) + ODRDiagDeclNote( + SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplateParameterDifferentDefaultArgument) << SecondTemplate << (i + 1) << SecondDefaultArgument; ParameterMismatch = true; break; @@ -10948,13 +11179,14 @@ void ASTReader::diagnoseOdrViolations() { if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) { - ODRDiagError(FirstTemplate->getLocation(), - FirstTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclError(FirstRecord, FirstModule, + FirstTemplate->getLocation(), + FirstTemplate->getSourceRange(), + FunctionTemplatePackParameter) << FirstTemplate << (i + 1) << FirstNTTPD->isParameterPack(); - ODRDiagNote(SecondTemplate->getLocation(), - SecondTemplate->getSourceRange(), - FunctionTemplatePackParameter) + ODRDiagDeclNote(SecondModule, SecondTemplate->getLocation(), + SecondTemplate->getSourceRange(), + FunctionTemplatePackParameter) << SecondTemplate << (i + 1) << SecondNTTPD->isParameterPack(); ParameterMismatch = true; @@ -11181,7 +11413,7 @@ void ASTReader::diagnoseOdrViolations() { for (auto *D : Enum->decls()) { // Due to decl merging, the first EnumDecl is the parent of // Decls in both records. - if (!ODRHash::isWhitelistedDecl(D, FirstEnum)) + if (!ODRHash::isDeclToBeProcessed(D, FirstEnum)) continue; assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind"); Hashes.emplace_back(cast<EnumConstantDecl>(D), @@ -11494,8 +11726,8 @@ public: OMPClauseReader(ASTRecordReader &Record) : Record(Record), Context(Record.getContext()) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" OMPClause *readClause(); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -11509,134 +11741,152 @@ OMPClause *ASTRecordReader::readOMPClause() { OMPClause *OMPClauseReader::readClause() { OMPClause *C = nullptr; - switch (Record.readInt()) { - case OMPC_if: + switch (llvm::omp::Clause(Record.readInt())) { + case llvm::omp::OMPC_if: C = new (Context) OMPIfClause(); break; - case OMPC_final: + case llvm::omp::OMPC_final: C = new (Context) OMPFinalClause(); break; - case OMPC_num_threads: + case llvm::omp::OMPC_num_threads: C = new (Context) OMPNumThreadsClause(); break; - case OMPC_safelen: + case llvm::omp::OMPC_safelen: C = new (Context) OMPSafelenClause(); break; - case OMPC_simdlen: + case llvm::omp::OMPC_simdlen: C = new (Context) OMPSimdlenClause(); break; - case OMPC_allocator: + case llvm::omp::OMPC_allocator: C = new (Context) OMPAllocatorClause(); break; - case OMPC_collapse: + case llvm::omp::OMPC_collapse: C = new (Context) OMPCollapseClause(); break; - case OMPC_default: + case llvm::omp::OMPC_default: C = new (Context) OMPDefaultClause(); break; - case OMPC_proc_bind: + case llvm::omp::OMPC_proc_bind: C = new (Context) OMPProcBindClause(); break; - case OMPC_schedule: + case llvm::omp::OMPC_schedule: C = new (Context) OMPScheduleClause(); break; - case OMPC_ordered: + case llvm::omp::OMPC_ordered: C = OMPOrderedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nowait: + case llvm::omp::OMPC_nowait: C = new (Context) OMPNowaitClause(); break; - case OMPC_untied: + case llvm::omp::OMPC_untied: C = new (Context) OMPUntiedClause(); break; - case OMPC_mergeable: + case llvm::omp::OMPC_mergeable: C = new (Context) OMPMergeableClause(); break; - case OMPC_read: + case llvm::omp::OMPC_read: C = new (Context) OMPReadClause(); break; - case OMPC_write: + case llvm::omp::OMPC_write: C = new (Context) OMPWriteClause(); break; - case OMPC_update: - C = new (Context) OMPUpdateClause(); + case llvm::omp::OMPC_update: + C = OMPUpdateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_capture: + case llvm::omp::OMPC_capture: C = new (Context) OMPCaptureClause(); break; - case OMPC_seq_cst: + case llvm::omp::OMPC_seq_cst: C = new (Context) OMPSeqCstClause(); break; - case OMPC_threads: + case llvm::omp::OMPC_acq_rel: + C = new (Context) OMPAcqRelClause(); + break; + case llvm::omp::OMPC_acquire: + C = new (Context) OMPAcquireClause(); + break; + case llvm::omp::OMPC_release: + C = new (Context) OMPReleaseClause(); + break; + case llvm::omp::OMPC_relaxed: + C = new (Context) OMPRelaxedClause(); + break; + case llvm::omp::OMPC_threads: C = new (Context) OMPThreadsClause(); break; - case OMPC_simd: + case llvm::omp::OMPC_simd: C = new (Context) OMPSIMDClause(); break; - case OMPC_nogroup: + case llvm::omp::OMPC_nogroup: C = new (Context) OMPNogroupClause(); break; - case OMPC_unified_address: + case llvm::omp::OMPC_unified_address: C = new (Context) OMPUnifiedAddressClause(); break; - case OMPC_unified_shared_memory: + case llvm::omp::OMPC_unified_shared_memory: C = new (Context) OMPUnifiedSharedMemoryClause(); break; - case OMPC_reverse_offload: + case llvm::omp::OMPC_reverse_offload: C = new (Context) OMPReverseOffloadClause(); break; - case OMPC_dynamic_allocators: + case llvm::omp::OMPC_dynamic_allocators: C = new (Context) OMPDynamicAllocatorsClause(); break; - case OMPC_atomic_default_mem_order: + case llvm::omp::OMPC_atomic_default_mem_order: C = new (Context) OMPAtomicDefaultMemOrderClause(); break; - case OMPC_private: + case llvm::omp::OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_firstprivate: + case llvm::omp::OMPC_firstprivate: C = OMPFirstprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_lastprivate: + case llvm::omp::OMPC_lastprivate: C = OMPLastprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_shared: + case llvm::omp::OMPC_shared: C = OMPSharedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_reduction: - C = OMPReductionClause::CreateEmpty(Context, Record.readInt()); + case llvm::omp::OMPC_reduction: { + unsigned N = Record.readInt(); + auto Modifier = Record.readEnum<OpenMPReductionClauseModifier>(); + C = OMPReductionClause::CreateEmpty(Context, N, Modifier); break; - case OMPC_task_reduction: + } + case llvm::omp::OMPC_task_reduction: C = OMPTaskReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_in_reduction: + case llvm::omp::OMPC_in_reduction: C = OMPInReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_linear: + case llvm::omp::OMPC_linear: C = OMPLinearClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_aligned: + case llvm::omp::OMPC_aligned: C = OMPAlignedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyin: + case llvm::omp::OMPC_copyin: C = OMPCopyinClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyprivate: + case llvm::omp::OMPC_copyprivate: C = OMPCopyprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_flush: + case llvm::omp::OMPC_flush: C = OMPFlushClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_depend: { + case llvm::omp::OMPC_depobj: + C = OMPDepobjClause::CreateEmpty(Context); + break; + case llvm::omp::OMPC_depend: { unsigned NumVars = Record.readInt(); unsigned NumLoops = Record.readInt(); C = OMPDependClause::CreateEmpty(Context, NumVars, NumLoops); break; } - case OMPC_device: + case llvm::omp::OMPC_device: C = new (Context) OMPDeviceClause(); break; - case OMPC_map: { + case llvm::omp::OMPC_map: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11645,31 +11895,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPMapClause::CreateEmpty(Context, Sizes); break; } - case OMPC_num_teams: + case llvm::omp::OMPC_num_teams: C = new (Context) OMPNumTeamsClause(); break; - case OMPC_thread_limit: + case llvm::omp::OMPC_thread_limit: C = new (Context) OMPThreadLimitClause(); break; - case OMPC_priority: + case llvm::omp::OMPC_priority: C = new (Context) OMPPriorityClause(); break; - case OMPC_grainsize: + case llvm::omp::OMPC_grainsize: C = new (Context) OMPGrainsizeClause(); break; - case OMPC_num_tasks: + case llvm::omp::OMPC_num_tasks: C = new (Context) OMPNumTasksClause(); break; - case OMPC_hint: + case llvm::omp::OMPC_hint: C = new (Context) OMPHintClause(); break; - case OMPC_dist_schedule: + case llvm::omp::OMPC_dist_schedule: C = new (Context) OMPDistScheduleClause(); break; - case OMPC_defaultmap: + case llvm::omp::OMPC_defaultmap: C = new (Context) OMPDefaultmapClause(); break; - case OMPC_to: { + case llvm::omp::OMPC_to: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11678,7 +11928,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPToClause::CreateEmpty(Context, Sizes); break; } - case OMPC_from: { + case llvm::omp::OMPC_from: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11687,7 +11937,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPFromClause::CreateEmpty(Context, Sizes); break; } - case OMPC_use_device_ptr: { + case llvm::omp::OMPC_use_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11696,7 +11946,16 @@ OMPClause *OMPClauseReader::readClause() { C = OMPUseDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_is_device_ptr: { + case llvm::omp::OMPC_use_device_addr: { + OMPMappableExprListSizeTy Sizes; + Sizes.NumVars = Record.readInt(); + Sizes.NumUniqueDeclarations = Record.readInt(); + Sizes.NumComponentLists = Record.readInt(); + Sizes.NumComponents = Record.readInt(); + C = OMPUseDeviceAddrClause::CreateEmpty(Context, Sizes); + break; + } + case llvm::omp::OMPC_is_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11705,12 +11964,39 @@ OMPClause *OMPClauseReader::readClause() { C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_allocate: + case llvm::omp::OMPC_allocate: C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nontemporal: + case llvm::omp::OMPC_nontemporal: C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt()); break; + case llvm::omp::OMPC_inclusive: + C = OMPInclusiveClause::CreateEmpty(Context, Record.readInt()); + break; + case llvm::omp::OMPC_exclusive: + C = OMPExclusiveClause::CreateEmpty(Context, Record.readInt()); + break; + case llvm::omp::OMPC_order: + C = new (Context) OMPOrderClause(); + break; + case llvm::omp::OMPC_destroy: + C = new (Context) OMPDestroyClause(); + break; + case llvm::omp::OMPC_detach: + C = new (Context) OMPDetachClause(); + break; + case llvm::omp::OMPC_uses_allocators: + C = OMPUsesAllocatorsClause::CreateEmpty(Context, Record.readInt()); + break; + case llvm::omp::OMPC_affinity: + C = OMPAffinityClause::CreateEmpty(Context, Record.readInt()); + break; +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + default: + break; } assert(C && "Unknown OMPClause type"); @@ -11773,8 +12059,7 @@ void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) { } void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) { - C->setDefaultKind( - static_cast<OpenMPDefaultClauseKind>(Record.readInt())); + C->setDefaultKind(static_cast<llvm::omp::DefaultKind>(Record.readInt())); C->setLParenLoc(Record.readSourceLocation()); C->setDefaultKindKwLoc(Record.readSourceLocation()); } @@ -11810,6 +12095,11 @@ void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause *C) { C->setLParenLoc(Record.readSourceLocation()); } +void OMPClauseReader::VisitOMPDetachClause(OMPDetachClause *C) { + C->setEventHandler(Record.readSubExpr()); + C->setLParenLoc(Record.readSourceLocation()); +} + void OMPClauseReader::VisitOMPNowaitClause(OMPNowaitClause *) {} void OMPClauseReader::VisitOMPUntiedClause(OMPUntiedClause *) {} @@ -11820,18 +12110,34 @@ void OMPClauseReader::VisitOMPReadClause(OMPReadClause *) {} void OMPClauseReader::VisitOMPWriteClause(OMPWriteClause *) {} -void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *) {} +void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *C) { + if (C->isExtended()) { + C->setLParenLoc(Record.readSourceLocation()); + C->setArgumentLoc(Record.readSourceLocation()); + C->setDependencyKind(Record.readEnum<OpenMPDependClauseKind>()); + } +} void OMPClauseReader::VisitOMPCaptureClause(OMPCaptureClause *) {} void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {} +void OMPClauseReader::VisitOMPAcqRelClause(OMPAcqRelClause *) {} + +void OMPClauseReader::VisitOMPAcquireClause(OMPAcquireClause *) {} + +void OMPClauseReader::VisitOMPReleaseClause(OMPReleaseClause *) {} + +void OMPClauseReader::VisitOMPRelaxedClause(OMPRelaxedClause *) {} + void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {} void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {} void OMPClauseReader::VisitOMPNogroupClause(OMPNogroupClause *) {} +void OMPClauseReader::VisitOMPDestroyClause(OMPDestroyClause *) {} + void OMPClauseReader::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {} void OMPClauseReader::VisitOMPUnifiedSharedMemoryClause( @@ -11927,6 +12233,7 @@ void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) { void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) { VisitOMPClauseWithPostUpdate(C); C->setLParenLoc(Record.readSourceLocation()); + C->setModifierLoc(Record.readSourceLocation()); C->setColonLoc(Record.readSourceLocation()); NestedNameSpecifierLoc NNSL = Record.readNestedNameSpecifierLoc(); DeclarationNameInfo DNI = Record.readDeclarationNameInfo(); @@ -11955,6 +12262,20 @@ void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) { for (unsigned i = 0; i != NumVars; ++i) Vars.push_back(Record.readSubExpr()); C->setReductionOps(Vars); + if (C->getModifier() == OMPC_REDUCTION_inscan) { + Vars.clear(); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setInscanCopyOps(Vars); + Vars.clear(); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setInscanCopyArrayTemps(Vars); + Vars.clear(); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setInscanCopyArrayElems(Vars); + } } void OMPClauseReader::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) { @@ -12129,8 +12450,14 @@ void OMPClauseReader::VisitOMPFlushClause(OMPFlushClause *C) { C->setVarRefs(Vars); } +void OMPClauseReader::VisitOMPDepobjClause(OMPDepobjClause *C) { + C->setDepobj(Record.readSubExpr()); + C->setLParenLoc(Record.readSourceLocation()); +} + void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) { C->setLParenLoc(Record.readSourceLocation()); + C->setModifier(Record.readSubExpr()); C->setDependencyKind( static_cast<OpenMPDependClauseKind>(Record.readInt())); C->setDependencyLoc(Record.readSourceLocation()); @@ -12147,13 +12474,15 @@ void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) { void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) { VisitOMPClauseWithPreInit(C); + C->setModifier(Record.readEnum<OpenMPDeviceClauseModifier>()); C->setDevice(Record.readSubExpr()); + C->setModifierLoc(Record.readSourceLocation()); C->setLParenLoc(Record.readSourceLocation()); } void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { C->setLParenLoc(Record.readSourceLocation()); - for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) { C->setMapTypeModifier( I, static_cast<OpenMPMapModifierKind>(Record.readInt())); C->setMapTypeModifierLoc(I, Record.readSourceLocation()); @@ -12427,6 +12756,48 @@ void OMPClauseReader::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) { C->setComponents(Components, ListSizes); } +void OMPClauseReader::VisitOMPUseDeviceAddrClause(OMPUseDeviceAddrClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + auto NumVars = C->varlist_size(); + auto UniqueDecls = C->getUniqueDeclarationsNum(); + auto TotalLists = C->getTotalComponentListNum(); + auto TotalComponents = C->getTotalComponentsNum(); + + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setVarRefs(Vars); + + SmallVector<ValueDecl *, 16> Decls; + Decls.reserve(UniqueDecls); + for (unsigned i = 0; i < UniqueDecls; ++i) + Decls.push_back(Record.readDeclAs<ValueDecl>()); + C->setUniqueDecls(Decls); + + SmallVector<unsigned, 16> ListsPerDecl; + ListsPerDecl.reserve(UniqueDecls); + for (unsigned i = 0; i < UniqueDecls; ++i) + ListsPerDecl.push_back(Record.readInt()); + C->setDeclNumLists(ListsPerDecl); + + SmallVector<unsigned, 32> ListSizes; + ListSizes.reserve(TotalLists); + for (unsigned i = 0; i < TotalLists; ++i) + ListSizes.push_back(Record.readInt()); + C->setComponentListSizes(ListSizes); + + SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components; + Components.reserve(TotalComponents); + for (unsigned i = 0; i < TotalComponents; ++i) { + Expr *AssociatedExpr = Record.readSubExpr(); + auto *AssociatedDecl = Record.readDeclAs<ValueDecl>(); + Components.push_back(OMPClauseMappableExprCommon::MappableComponent( + AssociatedExpr, AssociatedDecl)); + } + C->setComponents(Components, ListSizes); +} + void OMPClauseReader::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { C->setLParenLoc(Record.readSourceLocation()); auto NumVars = C->varlist_size(); @@ -12484,3 +12855,75 @@ void OMPClauseReader::VisitOMPNontemporalClause(OMPNontemporalClause *C) { Vars.push_back(Record.readSubExpr()); C->setPrivateRefs(Vars); } + +void OMPClauseReader::VisitOMPInclusiveClause(OMPInclusiveClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setVarRefs(Vars); +} + +void OMPClauseReader::VisitOMPExclusiveClause(OMPExclusiveClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setVarRefs(Vars); +} + +void OMPClauseReader::VisitOMPUsesAllocatorsClause(OMPUsesAllocatorsClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + unsigned NumOfAllocators = C->getNumberOfAllocators(); + SmallVector<OMPUsesAllocatorsClause::Data, 4> Data; + Data.reserve(NumOfAllocators); + for (unsigned I = 0; I != NumOfAllocators; ++I) { + OMPUsesAllocatorsClause::Data &D = Data.emplace_back(); + D.Allocator = Record.readSubExpr(); + D.AllocatorTraits = Record.readSubExpr(); + D.LParenLoc = Record.readSourceLocation(); + D.RParenLoc = Record.readSourceLocation(); + } + C->setAllocatorsData(Data); +} + +void OMPClauseReader::VisitOMPAffinityClause(OMPAffinityClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + C->setModifier(Record.readSubExpr()); + C->setColonLoc(Record.readSourceLocation()); + unsigned NumOfLocators = C->varlist_size(); + SmallVector<Expr *, 4> Locators; + Locators.reserve(NumOfLocators); + for (unsigned I = 0; I != NumOfLocators; ++I) + Locators.push_back(Record.readSubExpr()); + C->setVarRefs(Locators); +} + +void OMPClauseReader::VisitOMPOrderClause(OMPOrderClause *C) { + C->setKind(Record.readEnum<OpenMPOrderClauseKind>()); + C->setLParenLoc(Record.readSourceLocation()); + C->setKindKwLoc(Record.readSourceLocation()); +} + +OMPTraitInfo *ASTRecordReader::readOMPTraitInfo() { + OMPTraitInfo &TI = getContext().getNewOMPTraitInfo(); + TI.Sets.resize(readUInt32()); + for (auto &Set : TI.Sets) { + Set.Kind = readEnum<llvm::omp::TraitSet>(); + Set.Selectors.resize(readUInt32()); + for (auto &Selector : Set.Selectors) { + Selector.Kind = readEnum<llvm::omp::TraitSelector>(); + Selector.ScoreOrCondition = nullptr; + if (readBool()) + Selector.ScoreOrCondition = readExprRef(); + Selector.Properties.resize(readUInt32()); + for (auto &Property : Selector.Properties) + Property.Kind = readEnum<llvm::omp::TraitProperty>(); + } + } + return &TI; +} diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 96a7d5ae0a31..eef4ab16ec15 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -365,6 +365,7 @@ namespace clang { void VisitCXXConversionDecl(CXXConversionDecl *D); void VisitFieldDecl(FieldDecl *FD); void VisitMSPropertyDecl(MSPropertyDecl *FD); + void VisitMSGuidDecl(MSGuidDecl *D); void VisitIndirectFieldDecl(IndirectFieldDecl *FD); RedeclarableResult VisitVarDeclImpl(VarDecl *D); void VisitVarDecl(VarDecl *VD) { VisitVarDeclImpl(VD); } @@ -375,6 +376,7 @@ namespace clang { void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); DeclID VisitTemplateDecl(TemplateDecl *D); void VisitConceptDecl(ConceptDecl *D); + void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D); RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D); @@ -554,7 +556,7 @@ void ASTDeclReader::Visit(Decl *D) { void ASTDeclReader::VisitDecl(Decl *D) { if (D->isTemplateParameter() || D->isTemplateParameterPack() || - isa<ParmVarDecl>(D)) { + isa<ParmVarDecl>(D) || isa<ObjCTypeParamDecl>(D)) { // We don't want to deserialize the DeclContext of a template // parameter or of a parameter of a function template immediately. These // entities might be used in the formulation of its DeclContext (for @@ -1282,10 +1284,9 @@ void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { QualType T = Record.readType(); TypeSourceInfo *TSI = readTypeSourceInfo(); D->setType(T, TSI); - D->setPropertyAttributes( - (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt()); + D->setPropertyAttributes((ObjCPropertyAttribute::Kind)Record.readInt()); D->setPropertyAttributesAsWritten( - (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt()); + (ObjCPropertyAttribute::Kind)Record.readInt()); D->setPropertyImplementation( (ObjCPropertyDecl::PropertyControl)Record.readInt()); DeclarationName GetterName = Record.readDeclarationName(); @@ -1361,6 +1362,19 @@ void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) { PD->SetterId = Record.readIdentifier(); } +void ASTDeclReader::VisitMSGuidDecl(MSGuidDecl *D) { + VisitValueDecl(D); + D->PartVal.Part1 = Record.readInt(); + D->PartVal.Part2 = Record.readInt(); + D->PartVal.Part3 = Record.readInt(); + for (auto &C : D->PartVal.Part4And5) + C = Record.readInt(); + + // Add this GUID to the AST context's lookup structure, and merge if needed. + if (MSGuidDecl *Existing = Reader.getContext().MSGuidDecls.GetOrInsertNode(D)) + Reader.getContext().setPrimaryMergedDecl(D, Existing->getCanonicalDecl()); +} + void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { VisitValueDecl(FD); @@ -1979,8 +1993,8 @@ void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { void ASTDeclReader::VisitImportDecl(ImportDecl *D) { VisitDecl(D); - D->ImportedAndComplete.setPointer(readModule()); - D->ImportedAndComplete.setInt(Record.readInt()); + D->ImportedModule = readModule(); + D->setImportComplete(Record.readInt()); auto *StoredLocs = D->getTrailingObjects<SourceLocation>(); for (unsigned I = 0, N = Record.back(); I != N; ++I) StoredLocs[I] = readSourceLocation(); @@ -2037,6 +2051,9 @@ void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) { mergeMergeable(D); } +void ASTDeclReader::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) { +} + ASTDeclReader::RedeclarableResult ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { RedeclarableResult Redecl = VisitRedeclarable(D); @@ -2313,12 +2330,12 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record.readInt()); - if (Record.readInt()) { + if (Record.readBool()) { NestedNameSpecifierLoc NNS = Record.readNestedNameSpecifierLoc(); DeclarationNameInfo DN = Record.readDeclarationNameInfo(); - ConceptDecl *NamedConcept = cast<ConceptDecl>(Record.readDecl()); + ConceptDecl *NamedConcept = Record.readDeclAs<ConceptDecl>(); const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; - if (Record.readInt()) + if (Record.readBool()) ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); Expr *ImmediatelyDeclaredConstraint = Record.readExpr(); D->setTypeConstraint(NNS, DN, /*FoundDecl=*/nullptr, NamedConcept, @@ -2336,6 +2353,8 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { // TemplateParmPosition. D->setDepth(Record.readInt()); D->setPosition(Record.readInt()); + if (D->hasPlaceholderTypeConstraint()) + D->setPlaceholderTypeConstraint(Record.readExpr()); if (D->isExpandedParameterPack()) { auto TypesAndInfos = D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); @@ -2750,6 +2769,8 @@ public: return Reader.readVersionTuple(); } + OMPTraitInfo *readOMPTraitInfo() { return Reader.readOMPTraitInfo(); } + template <typename T> T *GetLocalDeclAs(uint32_t LocalID) { return Reader.GetLocalDeclAs<T>(LocalID); } @@ -2834,7 +2855,8 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { isa<PragmaDetectMismatchDecl>(D)) return true; if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) || - isa<OMPDeclareMapperDecl>(D) || isa<OMPAllocateDecl>(D)) + isa<OMPDeclareMapperDecl>(D) || isa<OMPAllocateDecl>(D) || + isa<OMPRequiresDecl>(D)) return !D->getDeclContext()->isFunctionOrMethod(); if (const auto *Var = dyn_cast<VarDecl>(D)) return Var->isFileVarDecl() && @@ -2859,7 +2881,7 @@ ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) { const DeclOffset &DOffs = M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS]; Loc = TranslateSourceLocation(*M, DOffs.getLocation()); - return RecordLocation(M, DOffs.BitOffset); + return RecordLocation(M, DOffs.getBitOffset(M->DeclsBlockStartOffset)); } ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) { @@ -2869,11 +2891,12 @@ ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) { return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset); } -uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) { +uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset) { return LocalOffset + M.GlobalBitOffset; } -static bool isSameTemplateParameterList(const TemplateParameterList *X, +static bool isSameTemplateParameterList(const ASTContext &C, + const TemplateParameterList *X, const TemplateParameterList *Y); /// Determine whether two template parameters are similar enough @@ -2885,7 +2908,32 @@ static bool isSameTemplateParameter(const NamedDecl *X, if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) { const auto *TY = cast<TemplateTypeParmDecl>(Y); - return TX->isParameterPack() == TY->isParameterPack(); + if (TX->isParameterPack() != TY->isParameterPack()) + return false; + if (TX->hasTypeConstraint() != TY->hasTypeConstraint()) + return false; + if (TX->hasTypeConstraint()) { + const TypeConstraint *TXTC = TX->getTypeConstraint(); + const TypeConstraint *TYTC = TY->getTypeConstraint(); + if (TXTC->getNamedConcept() != TYTC->getNamedConcept()) + return false; + if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs()) + return false; + if (TXTC->hasExplicitTemplateArgs()) { + const auto *TXTCArgs = TXTC->getTemplateArgsAsWritten(); + const auto *TYTCArgs = TYTC->getTemplateArgsAsWritten(); + if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs) + return false; + llvm::FoldingSetNodeID XID, YID; + for (const auto &ArgLoc : TXTCArgs->arguments()) + ArgLoc.getArgument().Profile(XID, X->getASTContext()); + for (const auto &ArgLoc : TYTCArgs->arguments()) + ArgLoc.getArgument().Profile(YID, Y->getASTContext()); + if (XID != YID) + return false; + } + } + return true; } if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { @@ -2897,7 +2945,8 @@ static bool isSameTemplateParameter(const NamedDecl *X, const auto *TX = cast<TemplateTemplateParmDecl>(X); const auto *TY = cast<TemplateTemplateParmDecl>(Y); return TX->isParameterPack() == TY->isParameterPack() && - isSameTemplateParameterList(TX->getTemplateParameters(), + isSameTemplateParameterList(TX->getASTContext(), + TX->getTemplateParameters(), TY->getTemplateParameters()); } @@ -2950,7 +2999,8 @@ static bool isSameQualifier(const NestedNameSpecifier *X, /// Determine whether two template parameter lists are similar enough /// that they may be used in declarations of the same template. -static bool isSameTemplateParameterList(const TemplateParameterList *X, +static bool isSameTemplateParameterList(const ASTContext &C, + const TemplateParameterList *X, const TemplateParameterList *Y) { if (X->size() != Y->size()) return false; @@ -2959,6 +3009,18 @@ static bool isSameTemplateParameterList(const TemplateParameterList *X, if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I))) return false; + const Expr *XRC = X->getRequiresClause(); + const Expr *YRC = Y->getRequiresClause(); + if (!XRC != !YRC) + return false; + if (XRC) { + llvm::FoldingSetNodeID XRCID, YRCID; + XRC->Profile(XRCID, C, /*Canonical=*/true); + YRC->Profile(YRCID, C, /*Canonical=*/true); + if (XRCID != YRCID) + return false; + } + return true; } @@ -2995,7 +3057,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A, return true; } -/// Determine whether the two declarations refer to the same entity. +/// Determine whether the two declarations refer to the same entity.pr static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!"); @@ -3070,6 +3132,19 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { } ASTContext &C = FuncX->getASTContext(); + + const Expr *XRC = FuncX->getTrailingRequiresClause(); + const Expr *YRC = FuncY->getTrailingRequiresClause(); + if (!XRC != !YRC) + return false; + if (XRC) { + llvm::FoldingSetNodeID XRCID, YRCID; + XRC->Profile(XRCID, C, /*Canonical=*/true); + YRC->Profile(YRCID, C, /*Canonical=*/true); + if (XRCID != YRCID) + return false; + } + auto GetTypeAsWritten = [](const FunctionDecl *FD) { // Map to the first declaration that we've already merged into this one. // The TSI of redeclarations might not match (due to calling conventions @@ -3093,6 +3168,7 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { return true; return false; } + return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() && hasSameOverloadableAttrs(FuncX, FuncY); } @@ -3132,7 +3208,8 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { const auto *TemplateY = cast<TemplateDecl>(Y); return isSameEntity(TemplateX->getTemplatedDecl(), TemplateY->getTemplatedDecl()) && - isSameTemplateParameterList(TemplateX->getTemplateParameters(), + isSameTemplateParameterList(TemplateX->getASTContext(), + TemplateX->getTemplateParameters(), TemplateY->getTemplateParameters()); } @@ -3819,13 +3896,19 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { HasTypeConstraint); break; } - case DECL_NON_TYPE_TEMPLATE_PARM: - D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID); + case DECL_NON_TYPE_TEMPLATE_PARM: { + bool HasTypeConstraint = Record.readInt(); + D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, + HasTypeConstraint); break; - case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: + } + case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: { + bool HasTypeConstraint = Record.readInt(); D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, - Record.readInt()); + Record.readInt(), + HasTypeConstraint); break; + } case DECL_TEMPLATE_TEMPLATE_PARM: D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID); break; @@ -3839,6 +3922,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_CONCEPT: D = ConceptDecl::CreateDeserialized(Context, ID); break; + case DECL_REQUIRES_EXPR_BODY: + D = RequiresExprBodyDecl::CreateDeserialized(Context, ID); + break; case DECL_STATIC_ASSERT: D = StaticAssertDecl::CreateDeserialized(Context, ID); break; @@ -3905,6 +3991,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_MS_PROPERTY: D = MSPropertyDecl::CreateDeserialized(Context, ID); break; + case DECL_MS_GUID: + D = MSGuidDecl::CreateDeserialized(Context, ID); + break; case DECL_CAPTURED: D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt()); break; diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f558c26b5f1e..a40c5499a6d7 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Serialization/ASTRecordReader.h" #include "clang/AST/ASTConcept.h" #include "clang/AST/ASTContext.h" #include "clang/AST/AttrIterator.h" @@ -22,6 +21,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" @@ -49,6 +49,8 @@ #include "clang/Basic/TypeTraits.h" #include "clang/Lex/Token.h" #include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ASTRecordReader.h" +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -101,11 +103,12 @@ namespace clang { /// The number of record fields required for the Stmt class /// itself. - static const unsigned NumStmtFields = 1; + static const unsigned NumStmtFields = 0; /// The number of record fields required for the Expr class /// itself. - static const unsigned NumExprFields = NumStmtFields + 7; + static const unsigned NumExprFields = + NumStmtFields + llvm::BitWidth<ExprDependence> + 3; /// Read and initialize a ExplicitTemplateArgumentList structure. void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, @@ -137,7 +140,6 @@ void ASTStmtReader::ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, } void ASTStmtReader::VisitStmt(Stmt *S) { - S->setIsOMPStructuredBlock(Record.readInt()); assert(Record.getIdx() == NumStmtFields && "Incorrect statement field count"); } @@ -269,6 +271,8 @@ void ASTStmtReader::VisitWhileStmt(WhileStmt *S) { S->setConditionVariable(Record.getContext(), readDeclAs<VarDecl>()); S->setWhileLoc(readSourceLocation()); + S->setLParenLoc(readSourceLocation()); + S->setRParenLoc(readSourceLocation()); } void ASTStmtReader::VisitDoStmt(DoStmt *S) { @@ -511,10 +515,26 @@ void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { void ASTStmtReader::VisitExpr(Expr *E) { VisitStmt(E); E->setType(Record.readType()); - E->setTypeDependent(Record.readInt()); - E->setValueDependent(Record.readInt()); - E->setInstantiationDependent(Record.readInt()); - E->ExprBits.ContainsUnexpandedParameterPack = Record.readInt(); + + // FIXME: write and read all DependentFlags with a single call. + bool TypeDependent = Record.readInt(); + bool ValueDependent = Record.readInt(); + bool InstantiationDependent = Record.readInt(); + bool ContainsUnexpandedTemplateParameters = Record.readInt(); + bool ContainsErrors = Record.readInt(); + auto Deps = ExprDependence::None; + if (TypeDependent) + Deps |= ExprDependence::Type; + if (ValueDependent) + Deps |= ExprDependence::Value; + if (InstantiationDependent) + Deps |= ExprDependence::Instantiation; + if (ContainsUnexpandedTemplateParameters) + Deps |= ExprDependence::UnexpandedPack; + if (ContainsErrors) + Deps |= ExprDependence::Error; + E->setDependence(Deps); + E->setValueKind(static_cast<ExprValueKind>(Record.readInt())); E->setObjectKind(static_cast<ExprObjectKind>(Record.readInt())); assert(Record.getIdx() == NumExprFields && @@ -523,18 +543,35 @@ void ASTStmtReader::VisitExpr(Expr *E) { void ASTStmtReader::VisitConstantExpr(ConstantExpr *E) { VisitExpr(E); - E->ConstantExprBits.ResultKind = Record.readInt(); - switch (E->ConstantExprBits.ResultKind) { - case ConstantExpr::RSK_Int64: { + + auto StorageKind = Record.readInt(); + assert(E->ConstantExprBits.ResultKind == StorageKind && "Wrong ResultKind!"); + + E->ConstantExprBits.APValueKind = Record.readInt(); + E->ConstantExprBits.IsUnsigned = Record.readInt(); + E->ConstantExprBits.BitWidth = Record.readInt(); + E->ConstantExprBits.HasCleanup = false; // Not serialized, see below. + E->ConstantExprBits.IsImmediateInvocation = Record.readInt(); + + switch (StorageKind) { + case ConstantExpr::RSK_None: + break; + + case ConstantExpr::RSK_Int64: E->Int64Result() = Record.readInt(); - uint64_t tmp = Record.readInt(); - E->ConstantExprBits.IsUnsigned = tmp & 0x1; - E->ConstantExprBits.BitWidth = tmp >> 1; break; - } + case ConstantExpr::RSK_APValue: E->APValueResult() = Record.readAPValue(); + if (E->APValueResult().needsCleanup()) { + E->ConstantExprBits.HasCleanup = true; + Record.getContext().addDestruction(&E->APValueResult()); + } + break; + default: + llvm_unreachable("unexpected ResultKind!"); } + E->setSubExpr(Record.readSubExpr()); } @@ -587,6 +624,7 @@ void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) { void ASTStmtReader::VisitFixedPointLiteral(FixedPointLiteral *E) { VisitExpr(E); E->setLocation(readSourceLocation()); + E->setScale(Record.readInt()); E->setValue(Record.getContext(), Record.readAPInt()); } @@ -663,10 +701,14 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) { void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); + bool hasFP_Features = Record.readInt(); + assert(hasFP_Features == E->hasStoredFPFeatures()); E->setSubExpr(Record.readSubExpr()); E->setOpcode((UnaryOperator::Opcode)Record.readInt()); E->setOperatorLoc(readSourceLocation()); E->setCanOverflow(Record.readInt()); + if (hasFP_Features) + E->setStoredFPFeatures(FPOptionsOverride(Record.readInt())); } void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) { @@ -724,27 +766,15 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { E->setRParenLoc(readSourceLocation()); } -void ASTStmtReader::VisitConceptSpecializationExpr( - ConceptSpecializationExpr *E) { - VisitExpr(E); - unsigned NumTemplateArgs = Record.readInt(); - E->NestedNameSpec = Record.readNestedNameSpecifierLoc(); - E->TemplateKWLoc = Record.readSourceLocation(); - E->ConceptName = Record.readDeclarationNameInfo(); - E->NamedConcept = readDeclAs<ConceptDecl>(); - E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); - llvm::SmallVector<TemplateArgument, 4> Args; - for (unsigned I = 0; I < NumTemplateArgs; ++I) - Args.push_back(Record.readTemplateArgument()); - E->setTemplateArguments(Args); +static ConstraintSatisfaction +readConstraintSatisfaction(ASTRecordReader &Record) { ConstraintSatisfaction Satisfaction; Satisfaction.IsSatisfied = Record.readInt(); if (!Satisfaction.IsSatisfied) { unsigned NumDetailRecords = Record.readInt(); for (unsigned i = 0; i != NumDetailRecords; ++i) { Expr *ConstraintExpr = Record.readExpr(); - bool IsDiagnostic = Record.readInt(); - if (IsDiagnostic) { + if (/* IsDiagnostic */Record.readInt()) { SourceLocation DiagLocation = Record.readSourceLocation(); std::string DiagMessage = Record.readString(); Satisfaction.Details.emplace_back( @@ -755,8 +785,138 @@ void ASTStmtReader::VisitConceptSpecializationExpr( Satisfaction.Details.emplace_back(ConstraintExpr, Record.readExpr()); } } - E->Satisfaction = ASTConstraintSatisfaction::Create(Record.getContext(), - Satisfaction); + return Satisfaction; +} + +void ASTStmtReader::VisitConceptSpecializationExpr( + ConceptSpecializationExpr *E) { + VisitExpr(E); + unsigned NumTemplateArgs = Record.readInt(); + E->NestedNameSpec = Record.readNestedNameSpecifierLoc(); + E->TemplateKWLoc = Record.readSourceLocation(); + E->ConceptName = Record.readDeclarationNameInfo(); + E->NamedConcept = readDeclAs<ConceptDecl>(); + E->FoundDecl = Record.readDeclAs<NamedDecl>(); + E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); + llvm::SmallVector<TemplateArgument, 4> Args; + for (unsigned I = 0; I < NumTemplateArgs; ++I) + Args.push_back(Record.readTemplateArgument()); + E->setTemplateArguments(Args); + E->Satisfaction = E->isValueDependent() ? nullptr : + ASTConstraintSatisfaction::Create(Record.getContext(), + readConstraintSatisfaction(Record)); +} + +static concepts::Requirement::SubstitutionDiagnostic * +readSubstitutionDiagnostic(ASTRecordReader &Record) { + std::string SubstitutedEntity = Record.readString(); + SourceLocation DiagLoc = Record.readSourceLocation(); + std::string DiagMessage = Record.readString(); + return new (Record.getContext()) + concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc, + DiagMessage}; +} + +void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) { + VisitExpr(E); + unsigned NumLocalParameters = Record.readInt(); + unsigned NumRequirements = Record.readInt(); + E->RequiresExprBits.RequiresKWLoc = Record.readSourceLocation(); + E->RequiresExprBits.IsSatisfied = Record.readInt(); + E->Body = Record.readDeclAs<RequiresExprBodyDecl>(); + llvm::SmallVector<ParmVarDecl *, 4> LocalParameters; + for (unsigned i = 0; i < NumLocalParameters; ++i) + LocalParameters.push_back(cast<ParmVarDecl>(Record.readDecl())); + std::copy(LocalParameters.begin(), LocalParameters.end(), + E->getTrailingObjects<ParmVarDecl *>()); + llvm::SmallVector<concepts::Requirement *, 4> Requirements; + for (unsigned i = 0; i < NumRequirements; ++i) { + auto RK = + static_cast<concepts::Requirement::RequirementKind>(Record.readInt()); + concepts::Requirement *R = nullptr; + switch (RK) { + case concepts::Requirement::RK_Type: { + auto Status = + static_cast<concepts::TypeRequirement::SatisfactionStatus>( + Record.readInt()); + if (Status == concepts::TypeRequirement::SS_SubstitutionFailure) + R = new (Record.getContext()) + concepts::TypeRequirement(readSubstitutionDiagnostic(Record)); + else + R = new (Record.getContext()) + concepts::TypeRequirement(Record.readTypeSourceInfo()); + } break; + case concepts::Requirement::RK_Simple: + case concepts::Requirement::RK_Compound: { + auto Status = + static_cast<concepts::ExprRequirement::SatisfactionStatus>( + Record.readInt()); + llvm::PointerUnion<concepts::Requirement::SubstitutionDiagnostic *, + Expr *> E; + if (Status == concepts::ExprRequirement::SS_ExprSubstitutionFailure) { + E = readSubstitutionDiagnostic(Record); + } else + E = Record.readExpr(); + + llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> Req; + ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr; + SourceLocation NoexceptLoc; + if (RK == concepts::Requirement::RK_Simple) { + Req.emplace(); + } else { + NoexceptLoc = Record.readSourceLocation(); + switch (/* returnTypeRequirementKind */Record.readInt()) { + case 0: + // No return type requirement. + Req.emplace(); + break; + case 1: { + // type-constraint + TemplateParameterList *TPL = Record.readTemplateParameterList(); + if (Status >= + concepts::ExprRequirement::SS_ConstraintsNotSatisfied) + SubstitutedConstraintExpr = + cast<ConceptSpecializationExpr>(Record.readExpr()); + Req.emplace(TPL); + } break; + case 2: + // Substitution failure + Req.emplace(readSubstitutionDiagnostic(Record)); + break; + } + } + if (Expr *Ex = E.dyn_cast<Expr *>()) + R = new (Record.getContext()) concepts::ExprRequirement( + Ex, RK == concepts::Requirement::RK_Simple, NoexceptLoc, + std::move(*Req), Status, SubstitutedConstraintExpr); + else + R = new (Record.getContext()) concepts::ExprRequirement( + E.get<concepts::Requirement::SubstitutionDiagnostic *>(), + RK == concepts::Requirement::RK_Simple, NoexceptLoc, + std::move(*Req)); + } break; + case concepts::Requirement::RK_Nested: { + if (/* IsSubstitutionDiagnostic */Record.readInt()) { + R = new (Record.getContext()) concepts::NestedRequirement( + readSubstitutionDiagnostic(Record)); + break; + } + Expr *E = Record.readExpr(); + if (E->isInstantiationDependent()) + R = new (Record.getContext()) concepts::NestedRequirement(E); + else + R = new (Record.getContext()) + concepts::NestedRequirement(Record.getContext(), E, + readConstraintSatisfaction(Record)); + } break; + } + if (!R) + continue; + Requirements.push_back(R); + } + std::copy(Requirements.begin(), Requirements.end(), + E->getTrailingObjects<concepts::Requirement *>()); + E->RBraceLoc = Record.readSourceLocation(); } void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { @@ -766,15 +926,68 @@ void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { E->setRBracketLoc(readSourceLocation()); } +void ASTStmtReader::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) { + VisitExpr(E); + E->setBase(Record.readSubExpr()); + E->setRowIdx(Record.readSubExpr()); + E->setColumnIdx(Record.readSubExpr()); + E->setRBracketLoc(readSourceLocation()); +} + void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { VisitExpr(E); E->setBase(Record.readSubExpr()); E->setLowerBound(Record.readSubExpr()); E->setLength(Record.readSubExpr()); - E->setColonLoc(readSourceLocation()); + E->setStride(Record.readSubExpr()); + E->setColonLocFirst(readSourceLocation()); + E->setColonLocSecond(readSourceLocation()); E->setRBracketLoc(readSourceLocation()); } +void ASTStmtReader::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { + VisitExpr(E); + unsigned NumDims = Record.readInt(); + E->setBase(Record.readSubExpr()); + SmallVector<Expr *, 4> Dims(NumDims); + for (unsigned I = 0; I < NumDims; ++I) + Dims[I] = Record.readSubExpr(); + E->setDimensions(Dims); + SmallVector<SourceRange, 4> SRs(NumDims); + for (unsigned I = 0; I < NumDims; ++I) + SRs[I] = readSourceRange(); + E->setBracketsRanges(SRs); + E->setLParenLoc(readSourceLocation()); + E->setRParenLoc(readSourceLocation()); +} + +void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) { + VisitExpr(E); + unsigned NumIters = Record.readInt(); + E->setIteratorKwLoc(readSourceLocation()); + E->setLParenLoc(readSourceLocation()); + E->setRParenLoc(readSourceLocation()); + for (unsigned I = 0; I < NumIters; ++I) { + E->setIteratorDeclaration(I, Record.readDeclRef()); + E->setAssignmentLoc(I, readSourceLocation()); + Expr *Begin = Record.readSubExpr(); + Expr *End = Record.readSubExpr(); + Expr *Step = Record.readSubExpr(); + SourceLocation ColonLoc = readSourceLocation(); + SourceLocation SecColonLoc; + if (Step) + SecColonLoc = readSourceLocation(); + E->setIteratorRange(I, Begin, ColonLoc, End, SecColonLoc, Step); + // Deserialize helpers + OMPIteratorHelperData HD; + HD.CounterVD = cast_or_null<VarDecl>(Record.readDeclRef()); + HD.Upper = Record.readSubExpr(); + HD.Update = Record.readSubExpr(); + HD.CounterUpdate = Record.readSubExpr(); + E->setHelper(I, HD); + } +} + void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); unsigned NumArgs = Record.readInt(); @@ -871,12 +1084,16 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) { } void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) { + bool hasFP_Features; + BinaryOperator::Opcode opc; VisitExpr(E); + E->setHasStoredFPFeatures(hasFP_Features = Record.readInt()); + E->setOpcode(opc = (BinaryOperator::Opcode)Record.readInt()); E->setLHS(Record.readSubExpr()); E->setRHS(Record.readSubExpr()); - E->setOpcode((BinaryOperator::Opcode)Record.readInt()); E->setOperatorLoc(readSourceLocation()); - E->setFPFeatures(FPOptions(Record.readInt())); + if (hasFP_Features) + E->setStoredFPFeatures(FPOptionsOverride(Record.readInt())); } void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) { @@ -1073,6 +1290,7 @@ void ASTStmtReader::VisitStmtExpr(StmtExpr *E) { E->setLParenLoc(readSourceLocation()); E->setRParenLoc(readSourceLocation()); E->setSubStmt(cast_or_null<CompoundStmt>(Record.readSubStmt())); + E->StmtExprBits.TemplateDepth = Record.readInt(); } void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) { @@ -1443,8 +1661,8 @@ void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); E->CXXOperatorCallExprBits.OperatorKind = Record.readInt(); - E->CXXOperatorCallExprBits.FPFeatures = Record.readInt(); E->Range = Record.readSourceRange(); + E->setFPFeatures(FPOptionsOverride(Record.readInt())); } void ASTStmtReader::VisitCXXRewrittenBinaryOperator( @@ -1490,19 +1708,23 @@ void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) { VisitExpr(E); unsigned NumCaptures = Record.readInt(); - assert(NumCaptures == E->NumCaptures);(void)NumCaptures; + (void)NumCaptures; + assert(NumCaptures == E->LambdaExprBits.NumCaptures); E->IntroducerRange = readSourceRange(); - E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record.readInt()); + E->LambdaExprBits.CaptureDefault = Record.readInt(); E->CaptureDefaultLoc = readSourceLocation(); - E->ExplicitParams = Record.readInt(); - E->ExplicitResultType = Record.readInt(); + E->LambdaExprBits.ExplicitParams = Record.readInt(); + E->LambdaExprBits.ExplicitResultType = Record.readInt(); E->ClosingBrace = readSourceLocation(); // Read capture initializers. for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(), - CEnd = E->capture_init_end(); + CEnd = E->capture_init_end(); C != CEnd; ++C) *C = Record.readSubExpr(); + + // The body will be lazily deserialized when needed from the call operator + // declaration. } void @@ -1532,6 +1754,10 @@ void ASTStmtReader::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) { return VisitCXXNamedCastExpr(E); } +void ASTStmtReader::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) { + return VisitCXXNamedCastExpr(E); +} + void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) { return VisitCXXNamedCastExpr(E); } @@ -1567,14 +1793,10 @@ void ASTStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) { void ASTStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) { VisitExpr(E); E->setSourceRange(readSourceRange()); - if (E->isTypeOperand()) { // typeid(int) - E->setTypeOperandSourceInfo( - readTypeSourceInfo()); - return; - } - - // typeid(42+2) - E->setExprOperand(Record.readSubExpr()); + if (E->isTypeOperand()) + E->Operand = readTypeSourceInfo(); + else + E->Operand = Record.readSubExpr(); } void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) { @@ -1687,9 +1909,17 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) { unsigned NumObjects = Record.readInt(); assert(NumObjects == E->getNumObjects()); - for (unsigned i = 0; i != NumObjects; ++i) - E->getTrailingObjects<BlockDecl *>()[i] = - readDeclAs<BlockDecl>(); + for (unsigned i = 0; i != NumObjects; ++i) { + unsigned CleanupKind = Record.readInt(); + ExprWithCleanups::CleanupObject Obj; + if (CleanupKind == COK_Block) + Obj = readDeclAs<BlockDecl>(); + else if (CleanupKind == COK_CompoundLiteral) + Obj = cast<CompoundLiteralExpr>(Record.readSubExpr()); + else + llvm_unreachable("unexpected cleanup object type"); + E->getTrailingObjects<ExprWithCleanups::CleanupObject>()[i] = Obj; + } E->ExprWithCleanupsBits.CleanupsHaveSideEffects = Record.readInt(); E->SubExpr = Record.readSubExpr(); @@ -1936,6 +2166,19 @@ void ASTStmtReader::VisitTypoExpr(TypoExpr *E) { llvm_unreachable("Cannot read TypoExpr nodes"); } +void ASTStmtReader::VisitRecoveryExpr(RecoveryExpr *E) { + VisitExpr(E); + unsigned NumArgs = Record.readInt(); + E->BeginLoc = readSourceLocation(); + E->EndLoc = readSourceLocation(); + assert( + (NumArgs == std::distance(E->children().begin(), E->children().end())) && + "Wrong NumArgs!"); + (void)NumArgs; + for (Stmt *&Child : E->children()) + Child = Record.readSubStmt(); +} + //===----------------------------------------------------------------------===// // Microsoft Expressions and Statements //===----------------------------------------------------------------------===// @@ -1958,16 +2201,11 @@ void ASTStmtReader::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) { void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) { VisitExpr(E); E->setSourceRange(readSourceRange()); - std::string UuidStr = readString(); - E->setUuidStr(StringRef(UuidStr).copy(Record.getContext())); - if (E->isTypeOperand()) { // __uuidof(ComType) - E->setTypeOperandSourceInfo( - readTypeSourceInfo()); - return; - } - - // __uuidof(expr) - E->setExprOperand(Record.readSubExpr()); + E->Guid = readDeclAs<MSGuidDecl>(); + if (E->isTypeOperand()) + E->Operand = readTypeSourceInfo(); + else + E->Operand = Record.readSubExpr(); } void ASTStmtReader::VisitSEHLeaveStmt(SEHLeaveStmt *S) { @@ -2111,6 +2349,7 @@ void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) { // The NumClauses field was read in ReadStmtFromStream. Record.skipInts(1); VisitOMPExecutableDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2120,6 +2359,7 @@ void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) { void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) { VisitOMPLoopDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2132,6 +2372,7 @@ void ASTStmtReader::VisitOMPSectionsDirective(OMPSectionsDirective *D) { // The NumClauses field was read in ReadStmtFromStream. Record.skipInts(1); VisitOMPExecutableDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2163,6 +2404,7 @@ void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) { void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) { VisitOMPLoopDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2177,6 +2419,7 @@ void ASTStmtReader::VisitOMPParallelMasterDirective( // The NumClauses field was read in ReadStmtFromStream. Record.skipInts(1); VisitOMPExecutableDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); } void ASTStmtReader::VisitOMPParallelSectionsDirective( @@ -2185,6 +2428,7 @@ void ASTStmtReader::VisitOMPParallelSectionsDirective( // The NumClauses field was read in ReadStmtFromStream. Record.skipInts(1); VisitOMPExecutableDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2226,6 +2470,20 @@ void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) { VisitOMPExecutableDirective(D); } +void ASTStmtReader::VisitOMPDepobjDirective(OMPDepobjDirective *D) { + VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + Record.skipInts(1); + VisitOMPExecutableDirective(D); +} + +void ASTStmtReader::VisitOMPScanDirective(OMPScanDirective *D) { + VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + Record.skipInts(1); + VisitOMPExecutableDirective(D); +} + void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) { VisitStmt(D); // The NumClauses field was read in ReadStmtFromStream. @@ -2278,11 +2536,14 @@ void ASTStmtReader::VisitOMPTargetParallelDirective( VisitStmt(D); Record.skipInts(1); VisitOMPExecutableDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); + D->setHasCancel(Record.readBool()); } void ASTStmtReader::VisitOMPTargetParallelForDirective( OMPTargetParallelForDirective *D) { VisitOMPLoopDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2310,6 +2571,7 @@ void ASTStmtReader::VisitOMPCancelDirective(OMPCancelDirective *D) { void ASTStmtReader::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) { VisitOMPLoopDirective(D); + D->setHasCancel(Record.readInt()); } void ASTStmtReader::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) { @@ -2319,6 +2581,7 @@ void ASTStmtReader::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) { void ASTStmtReader::VisitOMPMasterTaskLoopDirective( OMPMasterTaskLoopDirective *D) { VisitOMPLoopDirective(D); + D->setHasCancel(Record.readInt()); } void ASTStmtReader::VisitOMPMasterTaskLoopSimdDirective( @@ -2329,6 +2592,7 @@ void ASTStmtReader::VisitOMPMasterTaskLoopSimdDirective( void ASTStmtReader::VisitOMPParallelMasterTaskLoopDirective( OMPParallelMasterTaskLoopDirective *D) { VisitOMPLoopDirective(D); + D->setHasCancel(Record.readInt()); } void ASTStmtReader::VisitOMPParallelMasterTaskLoopSimdDirective( @@ -2349,6 +2613,7 @@ void ASTStmtReader::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) { void ASTStmtReader::VisitOMPDistributeParallelForDirective( OMPDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2389,6 +2654,7 @@ void ASTStmtReader::VisitOMPTeamsDistributeParallelForSimdDirective( void ASTStmtReader::VisitOMPTeamsDistributeParallelForDirective( OMPTeamsDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2407,6 +2673,7 @@ void ASTStmtReader::VisitOMPTargetTeamsDistributeDirective( void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForDirective( OMPTargetTeamsDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + D->setTaskReductionRefExpr(Record.readSubExpr()); D->setHasCancel(Record.readInt()); } @@ -2613,10 +2880,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_CONSTANT: S = ConstantExpr::CreateEmpty( - Context, - static_cast<ConstantExpr::ResultStorageKind>( - Record[ASTStmtReader::NumExprFields]), - Empty); + Context, static_cast<ConstantExpr::ResultStorageKind>( + /*StorageKind=*/Record[ASTStmtReader::NumExprFields])); break; case EXPR_PREDEFINED: @@ -2639,6 +2904,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = IntegerLiteral::Create(Context, Empty); break; + case EXPR_FIXEDPOINT_LITERAL: + S = FixedPointLiteral::Create(Context, Empty); + break; + case EXPR_FLOATING_LITERAL: S = FloatingLiteral::Create(Context, Empty); break; @@ -2670,7 +2939,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_UNARY_OPERATOR: - S = new (Context) UnaryOperator(Empty); + S = UnaryOperator::CreateEmpty(Context, + Record[ASTStmtReader::NumExprFields]); break; case EXPR_OFFSETOF: @@ -2687,15 +2957,34 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) ArraySubscriptExpr(Empty); break; + case EXPR_MATRIX_SUBSCRIPT: + S = new (Context) MatrixSubscriptExpr(Empty); + break; + case EXPR_OMP_ARRAY_SECTION: S = new (Context) OMPArraySectionExpr(Empty); break; + case EXPR_OMP_ARRAY_SHAPING: + S = OMPArrayShapingExpr::CreateEmpty( + Context, Record[ASTStmtReader::NumExprFields]); + break; + + case EXPR_OMP_ITERATOR: + S = OMPIteratorExpr::CreateEmpty(Context, + Record[ASTStmtReader::NumExprFields]); + break; + case EXPR_CALL: S = CallExpr::CreateEmpty( Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); break; + case EXPR_RECOVERY: + S = RecoveryExpr::CreateEmpty( + Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields]); + break; + case EXPR_MEMBER: S = MemberExpr::CreateEmpty(Context, Record[ASTStmtReader::NumExprFields], Record[ASTStmtReader::NumExprFields + 1], @@ -2704,11 +2993,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_BINARY_OPERATOR: - S = new (Context) BinaryOperator(Empty); + S = BinaryOperator::CreateEmpty(Context, + Record[ASTStmtReader::NumExprFields]); break; case EXPR_COMPOUND_ASSIGN_OPERATOR: - S = new (Context) CompoundAssignOperator(Empty); + S = CompoundAssignOperator::CreateEmpty( + Context, Record[ASTStmtReader::NumExprFields]); break; case EXPR_CONDITIONAL_OPERATOR: @@ -3054,6 +3345,16 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumStmtFields], Empty); break; + case STMT_OMP_DEPOBJ_DIRECTIVE: + S = OMPDepobjDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + + case STMT_OMP_SCAN_DIRECTIVE: + S = OMPScanDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + case STMT_OMP_ORDERED_DIRECTIVE: S = OMPOrderedDirective::CreateEmpty( Context, Record[ASTStmtReader::NumStmtFields], Empty); @@ -3331,11 +3632,20 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = CXXConstCastExpr::CreateEmpty(Context); break; + case EXPR_CXX_ADDRSPACE_CAST: + S = CXXAddrspaceCastExpr::CreateEmpty(Context); + break; + case EXPR_CXX_FUNCTIONAL_CAST: S = CXXFunctionalCastExpr::CreateEmpty(Context, /*PathSize*/ Record[ASTStmtReader::NumExprFields]); break; + case EXPR_BUILTIN_BIT_CAST: + assert(Record[ASTStmtReader::NumExprFields] == 0 && "Wrong PathSize!"); + S = new (Context) BuiltinBitCastExpr(Empty); + break; + case EXPR_USER_DEFINED_LITERAL: S = UserDefinedLiteral::CreateEmpty( Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); @@ -3566,11 +3876,18 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) DependentCoawaitExpr(Empty); break; - case EXPR_CONCEPT_SPECIALIZATION: + case EXPR_CONCEPT_SPECIALIZATION: { unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields]; S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs); break; - + } + + case EXPR_REQUIRES: + unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields]; + unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1]; + S = RequiresExpr::Create(Context, Empty, numLocalParameters, + numRequirement); + break; } // We hit a STMT_STOP, so we're done with this expression. diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 6eba48a1abe9..2345a12caeb2 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -10,14 +10,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/OpenMPClause.h" -#include "clang/Serialization/ASTRecordWriter.h" #include "ASTCommon.h" #include "ASTReaderInternals.h" #include "MultiOnDiskHashTable.h" -#include "clang/AST/AbstractTypeWriter.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTUnresolvedSet.h" +#include "clang/AST/AbstractTypeWriter.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" @@ -31,6 +29,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/LambdaCapture.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/RawCommentList.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -65,7 +64,9 @@ #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Weak.h" +#include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/ASTRecordWriter.h" #include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/ModuleFile.h" #include "clang/Serialization/ModuleFileExtension.h" @@ -288,6 +289,25 @@ void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { Record.AddSourceLocation(TL.getNameLoc()); } +void TypeLocWriter::VisitConstantMatrixTypeLoc(ConstantMatrixTypeLoc TL) { + Record.AddSourceLocation(TL.getAttrNameLoc()); + SourceRange range = TL.getAttrOperandParensRange(); + Record.AddSourceLocation(range.getBegin()); + Record.AddSourceLocation(range.getEnd()); + Record.AddStmt(TL.getAttrRowOperand()); + Record.AddStmt(TL.getAttrColumnOperand()); +} + +void TypeLocWriter::VisitDependentSizedMatrixTypeLoc( + DependentSizedMatrixTypeLoc TL) { + Record.AddSourceLocation(TL.getAttrNameLoc()); + SourceRange range = TL.getAttrOperandParensRange(); + Record.AddSourceLocation(range.getBegin()); + Record.AddSourceLocation(range.getEnd()); + Record.AddStmt(TL.getAttrRowOperand()); + Record.AddStmt(TL.getAttrColumnOperand()); +} + void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { Record.AddSourceLocation(TL.getLocalRangeBegin()); Record.AddSourceLocation(TL.getLParenLoc()); @@ -349,6 +369,18 @@ void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { Record.AddSourceLocation(TL.getNameLoc()); + Record.push_back(TL.isConstrained()); + if (TL.isConstrained()) { + Record.AddNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()); + Record.AddSourceLocation(TL.getTemplateKWLoc()); + Record.AddSourceLocation(TL.getConceptNameLoc()); + Record.AddDeclRef(TL.getFoundDecl()); + Record.AddSourceLocation(TL.getLAngleLoc()); + Record.AddSourceLocation(TL.getRAngleLoc()); + for (unsigned I = 0; I < TL.getNumArgs(); ++I) + Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(), + TL.getArgLocInfo(I)); + } } void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc( @@ -464,6 +496,14 @@ void TypeLocWriter::VisitPipeTypeLoc(PipeTypeLoc TL) { Record.AddSourceLocation(TL.getKWLoc()); } +void TypeLocWriter::VisitExtIntTypeLoc(clang::ExtIntTypeLoc TL) { + Record.AddSourceLocation(TL.getNameLoc()); +} +void TypeLocWriter::VisitDependentExtIntTypeLoc( + clang::DependentExtIntTypeLoc TL) { + Record.AddSourceLocation(TL.getNameLoc()); +} + void ASTWriter::WriteTypeAbbrevs() { using namespace llvm; @@ -488,6 +528,7 @@ void ASTWriter::WriteTypeAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult Abv->Add(BitCodeAbbrevOp(0)); // NoCallerSavedRegs Abv->Add(BitCodeAbbrevOp(0)); // NoCfCheck + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CmseNSCall // FunctionProtoType Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn @@ -558,6 +599,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_PREDEFINED); RECORD(EXPR_DECL_REF); RECORD(EXPR_INTEGER_LITERAL); + RECORD(EXPR_FIXEDPOINT_LITERAL); RECORD(EXPR_FLOATING_LITERAL); RECORD(EXPR_IMAGINARY_LITERAL); RECORD(EXPR_STRING_LITERAL); @@ -619,6 +661,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_CXX_DYNAMIC_CAST); RECORD(EXPR_CXX_REINTERPRET_CAST); RECORD(EXPR_CXX_CONST_CAST); + RECORD(EXPR_CXX_ADDRSPACE_CAST); RECORD(EXPR_CXX_FUNCTIONAL_CAST); RECORD(EXPR_USER_DEFINED_LITERAL); RECORD(EXPR_CXX_STD_INITIALIZER_LIST); @@ -744,6 +787,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DELETE_EXPRS_TO_ANALYZE); RECORD(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH); RECORD(PP_CONDITIONAL_STACK); + RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS); // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); @@ -885,6 +929,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_NON_TYPE_TEMPLATE_PARM); RECORD(DECL_TEMPLATE_TEMPLATE_PARM); RECORD(DECL_CONCEPT); + RECORD(DECL_REQUIRES_EXPR_BODY); RECORD(DECL_TYPE_ALIAS_TEMPLATE); RECORD(DECL_STATIC_ASSERT); RECORD(DECL_CXX_BASE_SPECIFIERS); @@ -917,6 +962,7 @@ void ASTWriter::WriteBlockInfoBlock() { BLOCK(UNHASHED_CONTROL_BLOCK); RECORD(SIGNATURE); + RECORD(AST_BLOCK_HASH); RECORD(DIAGNOSTIC_OPTIONS); RECORD(DIAG_PRAGMA_MAPPINGS); @@ -982,22 +1028,23 @@ adjustFilenameForRelocatableAST(const char *Filename, StringRef BaseDir) { return Filename + Pos; } -ASTFileSignature ASTWriter::createSignature(StringRef Bytes) { - // Calculate the hash till start of UNHASHED_CONTROL_BLOCK. +std::pair<ASTFileSignature, ASTFileSignature> +ASTWriter::createSignature(StringRef AllBytes, StringRef ASTBlockBytes) { llvm::SHA1 Hasher; - Hasher.update(ArrayRef<uint8_t>(Bytes.bytes_begin(), Bytes.size())); + Hasher.update(ASTBlockBytes); auto Hash = Hasher.result(); + ASTFileSignature ASTBlockHash = ASTFileSignature::create(Hash); - // Convert to an array [5*i32]. - ASTFileSignature Signature; - auto LShift = [&](unsigned char Val, unsigned Shift) { - return (uint32_t)Val << Shift; - }; - for (int I = 0; I != 5; ++I) - Signature[I] = LShift(Hash[I * 4 + 0], 24) | LShift(Hash[I * 4 + 1], 16) | - LShift(Hash[I * 4 + 2], 8) | LShift(Hash[I * 4 + 3], 0); + // Add the remaining bytes (i.e. bytes before the unhashed control block that + // are not part of the AST block). + Hasher.update( + AllBytes.take_front(ASTBlockBytes.bytes_end() - AllBytes.bytes_begin())); + Hasher.update( + AllBytes.take_back(AllBytes.bytes_end() - ASTBlockBytes.bytes_end())); + Hash = Hasher.result(); + ASTFileSignature Signature = ASTFileSignature::create(Hash); - return Signature; + return std::make_pair(ASTBlockHash, Signature); } ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP, @@ -1014,7 +1061,16 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP, ASTFileSignature Signature; if (WritingModule && PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) { - Signature = createSignature(StringRef(Buffer.begin(), StartOfUnhashedControl)); + ASTFileSignature ASTBlockHash; + auto ASTBlockStartByte = ASTBlockRange.first >> 3; + auto ASTBlockByteLength = (ASTBlockRange.second >> 3) - ASTBlockStartByte; + std::tie(ASTBlockHash, Signature) = createSignature( + StringRef(Buffer.begin(), StartOfUnhashedControl), + StringRef(Buffer.begin() + ASTBlockStartByte, ASTBlockByteLength)); + + Record.append(ASTBlockHash.begin(), ASTBlockHash.end()); + Stream.EmitRecord(AST_BLOCK_HASH, Record); + Record.clear(); Record.append(Signature.begin(), Signature.end()); Stream.EmitRecord(SIGNATURE, Record); Record.clear(); @@ -1119,7 +1175,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, BaseDirectory.assign(BaseDir.begin(), BaseDir.end()); } else if (!isysroot.empty()) { // Write out paths relative to the sysroot if possible. - BaseDirectory = isysroot; + BaseDirectory = std::string(isysroot); } // Module map file @@ -1705,7 +1761,8 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { llvm::SmallVector<Module *, 16> Worklist(1, WritingModule); while (!Worklist.empty()) { Module *M = Worklist.pop_back_val(); - if (!M->isAvailable()) + // We don't care about headers in unimportable submodules. + if (M->isUnimportable()) continue; // Map to disk files where possible, to pick up any missing stat @@ -1787,7 +1844,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { Filename, File->getSize(), getTimestampForOutput(File) }; HeaderFileInfoTrait::data_type Data = { - *HFI, HS.getModuleMap().findAllModulesForHeader(File), {} + *HFI, HS.getModuleMap().findResolvedModulesForHeader(File), {} }; Generator.insert(Key, Data, GeneratorTrait); ++NumHeaderSearchEntries; @@ -1865,6 +1922,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Enter the source manager block. Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 4); + const uint64_t SourceManagerBlockOffset = Stream.GetCurrentBitNo(); // Abbreviations for the various kinds of source-location entries. unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream); @@ -1877,6 +1935,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Write out the source location entry table. We skip the first // entry, which is always the same dummy entry. std::vector<uint32_t> SLocEntryOffsets; + uint64_t SLocEntryOffsetsBase = Stream.GetCurrentBitNo(); RecordData PreloadSLocs; SLocEntryOffsets.reserve(SourceMgr.local_sloc_entry_size() - 1); for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); @@ -1887,7 +1946,9 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, assert(&SourceMgr.getSLocEntry(FID) == SLoc); // Record the offset of this source-location entry. - SLocEntryOffsets.push_back(Stream.GetCurrentBitNo()); + uint64_t Offset = Stream.GetCurrentBitNo() - SLocEntryOffsetsBase; + assert((Offset >> 32) == 0 && "SLocEntry offset too large"); + SLocEntryOffsets.push_back(Offset); // Figure out which record code to use. unsigned Code; @@ -1995,12 +2056,14 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // total size + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // base offset Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { RecordData::value_type Record[] = { SOURCE_LOCATION_OFFSETS, SLocEntryOffsets.size(), - SourceMgr.getNextLocalOffset() - 1 /* skip dummy */}; + SourceMgr.getNextLocalOffset() - 1 /* skip dummy */, + SLocEntryOffsetsBase - SourceManagerBlockOffset}; Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, bytes(SLocEntryOffsets)); } @@ -2077,9 +2140,11 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule, /// Writes the block containing the serialized form of the /// preprocessor. void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { + uint64_t MacroOffsetsBase = Stream.GetCurrentBitNo(); + PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); if (PPRec) - WritePreprocessorDetail(*PPRec); + WritePreprocessorDetail(*PPRec, MacroOffsetsBase); RecordData Record; RecordData ModuleMacroRecord; @@ -2140,7 +2205,8 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { // identifier they belong to. for (const IdentifierInfo *Name : MacroIdentifiers) { MacroDirective *MD = PP.getLocalMacroDirectiveHistory(Name); - auto StartOffset = Stream.GetCurrentBitNo(); + uint64_t StartOffset = Stream.GetCurrentBitNo() - MacroOffsetsBase; + assert((StartOffset >> 32) == 0 && "Macro identifiers offset too large"); // Emit the macro directives in reverse source order. for (; MD; MD = MD->getPrevious()) { @@ -2213,14 +2279,12 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { // Record the local offset of this macro. unsigned Index = ID - FirstMacroID; - if (Index == MacroOffsets.size()) - MacroOffsets.push_back(Stream.GetCurrentBitNo()); - else { - if (Index > MacroOffsets.size()) - MacroOffsets.resize(Index + 1); + if (Index >= MacroOffsets.size()) + MacroOffsets.resize(Index + 1); - MacroOffsets[Index] = Stream.GetCurrentBitNo(); - } + uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase; + assert((Offset >> 32) == 0 && "Macro offset too large"); + MacroOffsets[Index] = Offset; AddIdentifierRef(Name, Record); AddSourceLocation(MI->getDefinitionLoc(), Record); @@ -2271,17 +2335,20 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { Abbrev->Add(BitCodeAbbrevOp(MACRO_OFFSET)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // base offset Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { RecordData::value_type Record[] = {MACRO_OFFSET, MacroOffsets.size(), - FirstMacroID - NUM_PREDEF_MACRO_IDS}; + FirstMacroID - NUM_PREDEF_MACRO_IDS, + MacroOffsetsBase - ASTBlockStartOffset}; Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, bytes(MacroOffsets)); } } -void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { +void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec, + uint64_t MacroOffsetsBase) { if (PPRec.local_begin() == PPRec.local_end()) return; @@ -2318,8 +2385,10 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) { Record.clear(); + uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase; + assert((Offset >> 32) == 0 && "Preprocessed entity offset too large"); PreprocessedEntityOffsets.push_back( - PPEntityOffset((*E)->getSourceRange(), Stream.GetCurrentBitNo())); + PPEntityOffset((*E)->getSourceRange(), Offset)); if (auto *MD = dyn_cast<MacroDefinitionRecord>(*E)) { // Record this macro definition's ID. @@ -2787,15 +2856,15 @@ void ASTWriter::WriteType(QualType T) { assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); // Emit the type's representation. - uint64_t Offset = ASTTypeWriter(*this).write(T); + uint64_t Offset = ASTTypeWriter(*this).write(T) - DeclTypesBlockStartOffset; // Record the offset for this type. unsigned Index = Idx.getIndex() - FirstTypeID; if (TypeOffsets.size() == Index) - TypeOffsets.push_back(Offset); + TypeOffsets.emplace_back(Offset); else if (TypeOffsets.size() < Index) { TypeOffsets.resize(Index + 1); - TypeOffsets[Index] = Offset; + TypeOffsets[Index].setBitOffset(Offset); } else { llvm_unreachable("Types emitted in wrong order"); } @@ -2862,8 +2931,10 @@ void ASTWriter::WriteTypeDeclOffsets() { void ASTWriter::WriteFileDeclIDsMap() { using namespace llvm; - SmallVector<std::pair<FileID, DeclIDInFileInfo *>, 64> SortedFileDeclIDs( - FileDeclIDs.begin(), FileDeclIDs.end()); + SmallVector<std::pair<FileID, DeclIDInFileInfo *>, 64> SortedFileDeclIDs; + SortedFileDeclIDs.reserve(FileDeclIDs.size()); + for (const auto &P : FileDeclIDs) + SortedFileDeclIDs.push_back(std::make_pair(P.first, P.second.get())); llvm::sort(SortedFileDeclIDs, llvm::less_first()); // Join the vectors of DeclIDs from all files. @@ -3889,8 +3960,8 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { } /// Write an FP_PRAGMA_OPTIONS block for the given FPOptions. -void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) { - RecordData::value_type Record[] = {Opts.getInt()}; +void ASTWriter::WriteFPPragmaOptions(const FPOptionsOverride &Opts) { + RecordData::value_type Record[] = {Opts.getAsOpaqueInt()}; Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record); } @@ -4101,6 +4172,26 @@ void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) { Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record); } +/// Write the state of 'pragma float_control' at the end of the module. +void ASTWriter::WriteFloatControlPragmaOptions(Sema &SemaRef) { + // Don't serialize pragma float_control state for modules, + // since it should only take effect on a per-submodule basis. + if (WritingModule) + return; + + RecordData Record; + Record.push_back(SemaRef.FpPragmaStack.CurrentValue); + AddSourceLocation(SemaRef.FpPragmaStack.CurrentPragmaLocation, Record); + Record.push_back(SemaRef.FpPragmaStack.Stack.size()); + for (const auto &StackEntry : SemaRef.FpPragmaStack.Stack) { + Record.push_back(StackEntry.Value); + AddSourceLocation(StackEntry.PragmaLocation, Record); + AddSourceLocation(StackEntry.PragmaPushLocation, Record); + AddString(StackEntry.StackSlotLabel, Record); + } + Stream.EmitRecord(FLOAT_CONTROL_PRAGMA_OPTIONS, Record); +} + void ASTWriter::WriteModuleFileExtension(Sema &SemaRef, ModuleFileExtensionWriter &Writer) { // Enter the extension block. @@ -4261,9 +4352,7 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream, } } -ASTWriter::~ASTWriter() { - llvm::DeleteContainerSeconds(FileDeclIDs); -} +ASTWriter::~ASTWriter() = default; const LangOptions &ASTWriter::getLangOpts() const { assert(WritingAST && "can't determine lang opts when not writing AST"); @@ -4356,6 +4445,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, RegisterPredefDecl(Context.VaListTagDecl, PREDEF_DECL_VA_LIST_TAG); RegisterPredefDecl(Context.BuiltinMSVaListDecl, PREDEF_DECL_BUILTIN_MS_VA_LIST_ID); + RegisterPredefDecl(Context.MSGuidTagDecl, + PREDEF_DECL_BUILTIN_MS_GUID_ID); RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID); RegisterPredefDecl(Context.MakeIntegerSeqDecl, PREDEF_DECL_MAKE_INTEGER_SEQ_ID); @@ -4475,7 +4566,10 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteControlBlock(PP, Context, isysroot, OutputFile); // Write the remaining AST contents. + Stream.FlushToWord(); + ASTBlockRange.first = Stream.GetCurrentBitNo(); Stream.EnterSubblock(AST_BLOCK_ID, 5); + ASTBlockStartOffset = Stream.GetCurrentBitNo(); // This is so that older clang versions, before the introduction // of the control block, can read and reject the newer PCH format. @@ -4606,9 +4700,9 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // c++-base-specifiers-id:i32 // type-id:i32) // - // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule or - // MK_ExplicitModule, then the module-name is the module name. Otherwise, - // it is the module file name. + // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule, + // MK_ExplicitModule or MK_ImplicitModule, then the module-name is the + // module name. Otherwise, it is the module file name. auto Abbrev = std::make_shared<BitCodeAbbrev>(); Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); @@ -4621,10 +4715,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, endian::Writer LE(Out, little); LE.write<uint8_t>(static_cast<uint8_t>(M.Kind)); - StringRef Name = - M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule - ? M.ModuleName - : M.FileName; + StringRef Name = M.isModule() ? M.ModuleName : M.FileName; LE.write<uint16_t>(Name.size()); Out.write(Name.data(), Name.size()); @@ -4658,11 +4749,17 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, Buffer.data(), Buffer.size()); } + // Build a record containing all of the DeclsToCheckForDeferredDiags. + RecordData DeclsToCheckForDeferredDiags; + for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) + AddDeclRef(D, DeclsToCheckForDeferredDiags); + RecordData DeclUpdatesOffsetsRecord; // Keep writing types, declarations, and declaration update records // until we've emitted all of them. Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5); + DeclTypesBlockStartOffset = Stream.GetCurrentBitNo(); WriteTypeAbbrevs(); WriteDeclAbbrevs(); do { @@ -4693,7 +4790,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteReferencedSelectorsPool(SemaRef); WriteLateParsedTemplates(SemaRef); WriteIdentifierTable(PP, SemaRef.IdResolver, isModule); - WriteFPPragmaOptions(SemaRef.getFPOptions()); + WriteFPPragmaOptions(SemaRef.CurFPFeatureOverrides()); WriteOpenCLExtensions(SemaRef); WriteOpenCLExtensionTypes(SemaRef); WriteCUDAPragmas(SemaRef); @@ -4749,6 +4846,11 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, if (!SemaDeclRefs.empty()) Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); + // Write the record containing decls to be checked for deferred diags. + if (!DeclsToCheckForDeferredDiags.empty()) + Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS, + DeclsToCheckForDeferredDiags); + // Write the record containing CUDA-specific declaration references. if (!CUDASpecialDeclRefs.empty()) Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs); @@ -4819,12 +4921,15 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteMSPointersToMembersPragmaOptions(SemaRef); } WritePackPragmaOptions(SemaRef); + WriteFloatControlPragmaOptions(SemaRef); // Some simple statistics RecordData::value_type Record[] = { NumStatements, NumMacros, NumLexicalDeclContexts, NumVisibleDeclContexts}; Stream.EmitRecord(STATISTICS, Record); Stream.ExitBlock(); + Stream.FlushToWord(); + ASTBlockRange.second = Stream.GetCurrentBitNo(); // Write the module file extension blocks. for (const auto &ExtWriter : ModuleFileExtensionWriters) @@ -5116,7 +5221,7 @@ MacroID ASTWriter::getMacroID(MacroInfo *MI) { return MacroIDs[MI]; } -uint64_t ASTWriter::getMacroDirectivesOffset(const IdentifierInfo *Name) { +uint32_t ASTWriter::getMacroDirectivesOffset(const IdentifierInfo *Name) { return IdentMacroDirectivesOffsetMap.lookup(Name); } @@ -5318,9 +5423,9 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { return; assert(SM.getSLocEntry(FID).isFile()); - DeclIDInFileInfo *&Info = FileDeclIDs[FID]; + std::unique_ptr<DeclIDInFileInfo> &Info = FileDeclIDs[FID]; if (!Info) - Info = new DeclIDInFileInfo(); + Info = std::make_unique<DeclIDInFileInfo>(); std::pair<unsigned, serialization::DeclID> LocDecl(Offset, ID); LocDeclIDsTy &Decls = Info->DeclIDs; @@ -5952,7 +6057,7 @@ void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D, void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { if (Chain && Chain->isProcessingUpdateRecords()) return; assert(!WritingAST && "Already writing the AST!"); - assert(D->isHidden() && "expected a hidden declaration"); + assert(!D->isUnconditionallyVisible() && "expected a hidden declaration"); DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M)); } @@ -6012,8 +6117,8 @@ class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> { public: OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void writeClause(OMPClause *C); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -6026,7 +6131,7 @@ void ASTRecordWriter::writeOMPClause(OMPClause *C) { } void OMPClauseWriter::writeClause(OMPClause *C) { - Record.push_back(C->getClauseKind()); + Record.push_back(unsigned(C->getClauseKind())); Visit(C); Record.AddSourceLocation(C->getBeginLoc()); Record.AddSourceLocation(C->getEndLoc()); @@ -6083,8 +6188,13 @@ void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) { Record.AddSourceLocation(C->getLParenLoc()); } +void OMPClauseWriter::VisitOMPDetachClause(OMPDetachClause *C) { + Record.AddStmt(C->getEventHandler()); + Record.AddSourceLocation(C->getLParenLoc()); +} + void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) { - Record.push_back(C->getDefaultKind()); + Record.push_back(unsigned(C->getDefaultKind())); Record.AddSourceLocation(C->getLParenLoc()); Record.AddSourceLocation(C->getDefaultKindKwLoc()); } @@ -6128,18 +6238,35 @@ void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {} void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {} -void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {} +void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *C) { + Record.push_back(C->isExtended() ? 1 : 0); + if (C->isExtended()) { + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getArgumentLoc()); + Record.writeEnum(C->getDependencyKind()); + } +} void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {} void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {} +void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {} + +void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {} + +void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {} + +void OMPClauseWriter::VisitOMPRelaxedClause(OMPRelaxedClause *) {} + void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {} void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {} void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {} +void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *) {} + void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); @@ -6194,8 +6321,10 @@ void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) { void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) { Record.push_back(C->varlist_size()); + Record.writeEnum(C->getModifier()); VisitOMPClauseWithPostUpdate(C); Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getModifierLoc()); Record.AddSourceLocation(C->getColonLoc()); Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); Record.AddDeclarationNameInfo(C->getNameInfo()); @@ -6209,6 +6338,14 @@ void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) { Record.AddStmt(E); for (auto *E : C->reduction_ops()) Record.AddStmt(E); + if (C->getModifier() == clang::OMPC_REDUCTION_inscan) { + for (auto *E : C->copy_ops()) + Record.AddStmt(E); + for (auto *E : C->copy_array_temps()) + Record.AddStmt(E); + for (auto *E : C->copy_array_elems()) + Record.AddStmt(E); + } } void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) { @@ -6321,10 +6458,16 @@ void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) { Record.AddStmt(VE); } +void OMPClauseWriter::VisitOMPDepobjClause(OMPDepobjClause *C) { + Record.AddStmt(C->getDepobj()); + Record.AddSourceLocation(C->getLParenLoc()); +} + void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { Record.push_back(C->varlist_size()); Record.push_back(C->getNumLoops()); Record.AddSourceLocation(C->getLParenLoc()); + Record.AddStmt(C->getModifier()); Record.push_back(C->getDependencyKind()); Record.AddSourceLocation(C->getDependencyLoc()); Record.AddSourceLocation(C->getColonLoc()); @@ -6336,7 +6479,9 @@ void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) { VisitOMPClauseWithPreInit(C); + Record.writeEnum(C->getModifier()); Record.AddStmt(C->getDevice()); + Record.AddSourceLocation(C->getModifierLoc()); Record.AddSourceLocation(C->getLParenLoc()); } @@ -6346,7 +6491,7 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) { Record.push_back(C->getMapTypeModifier(I)); Record.AddSourceLocation(C->getMapTypeModifierLoc(I)); } @@ -6504,6 +6649,26 @@ void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) { } } +void OMPClauseWriter::VisitOMPUseDeviceAddrClause(OMPUseDeviceAddrClause *C) { + Record.push_back(C->varlist_size()); + Record.push_back(C->getUniqueDeclarationsNum()); + Record.push_back(C->getTotalComponentListNum()); + Record.push_back(C->getTotalComponentsNum()); + Record.AddSourceLocation(C->getLParenLoc()); + for (auto *E : C->varlists()) + Record.AddStmt(E); + for (auto *D : C->all_decls()) + Record.AddDeclRef(D); + for (auto N : C->all_num_lists()) + Record.push_back(N); + for (auto N : C->all_lists_sizes()) + Record.push_back(N); + for (auto &M : C->all_components()) { + Record.AddStmt(M.getAssociatedExpression()); + Record.AddDeclRef(M.getAssociatedDeclaration()); + } +} + void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { Record.push_back(C->varlist_size()); Record.push_back(C->getUniqueDeclarationsNum()); @@ -6550,3 +6715,61 @@ void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) { for (auto *E : C->private_refs()) Record.AddStmt(E); } + +void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) { + Record.push_back(C->varlist_size()); + Record.AddSourceLocation(C->getLParenLoc()); + for (auto *VE : C->varlists()) + Record.AddStmt(VE); +} + +void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) { + Record.push_back(C->varlist_size()); + Record.AddSourceLocation(C->getLParenLoc()); + for (auto *VE : C->varlists()) + Record.AddStmt(VE); +} + +void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) { + Record.writeEnum(C->getKind()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getKindKwLoc()); +} + +void OMPClauseWriter::VisitOMPUsesAllocatorsClause(OMPUsesAllocatorsClause *C) { + Record.push_back(C->getNumberOfAllocators()); + Record.AddSourceLocation(C->getLParenLoc()); + for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) { + OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I); + Record.AddStmt(Data.Allocator); + Record.AddStmt(Data.AllocatorTraits); + Record.AddSourceLocation(Data.LParenLoc); + Record.AddSourceLocation(Data.RParenLoc); + } +} + +void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) { + Record.push_back(C->varlist_size()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddStmt(C->getModifier()); + Record.AddSourceLocation(C->getColonLoc()); + for (Expr *E : C->varlists()) + Record.AddStmt(E); +} + +void ASTRecordWriter::writeOMPTraitInfo(const OMPTraitInfo *TI) { + writeUInt32(TI->Sets.size()); + for (const auto &Set : TI->Sets) { + writeEnum(Set.Kind); + writeUInt32(Set.Selectors.size()); + for (const auto &Selector : Set.Selectors) { + writeEnum(Selector.Kind); + writeBool(Selector.ScoreOrCondition); + if (Selector.ScoreOrCondition) + writeExprRef(Selector.ScoreOrCondition); + writeUInt32(Selector.Properties.size()); + for (const auto &Property : Selector.Properties) + writeEnum(Property.Kind); + } + } +} diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index b2a8c118d401..eecdf89c791a 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -95,6 +95,7 @@ namespace clang { void VisitCXXConversionDecl(CXXConversionDecl *D); void VisitFieldDecl(FieldDecl *D); void VisitMSPropertyDecl(MSPropertyDecl *D); + void VisitMSGuidDecl(MSGuidDecl *D); void VisitIndirectFieldDecl(IndirectFieldDecl *D); void VisitVarDecl(VarDecl *D); void VisitImplicitParamDecl(ImplicitParamDecl *D); @@ -104,6 +105,7 @@ namespace clang { void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); void VisitTemplateDecl(TemplateDecl *D); void VisitConceptDecl(ConceptDecl *D); + void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D); void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); void VisitVarTemplateDecl(VarTemplateDecl *D); @@ -952,6 +954,17 @@ void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) { Code = serialization::DECL_MS_PROPERTY; } +void ASTDeclWriter::VisitMSGuidDecl(MSGuidDecl *D) { + VisitValueDecl(D); + MSGuidDecl::Parts Parts = D->getParts(); + Record.push_back(Parts.Part1); + Record.push_back(Parts.Part2); + Record.push_back(Parts.Part3); + for (auto C : Parts.Part4And5) + Record.push_back(C); + Code = serialization::DECL_MS_GUID; +} + void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { VisitValueDecl(D); Record.push_back(D->getChainingSize()); @@ -1010,16 +1023,15 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { if (D->getStorageDuration() == SD_Static) { bool ModulesCodegen = false; - if (!D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() && + if (Writer.WritingModule && + !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() && !isa<VarTemplateSpecializationDecl>(D)) { // When building a C++ Modules TS module interface unit, a strong // definition in the module interface is provided by the compilation of // that module interface unit, not by its users. (Inline variables are // still emitted in module users.) ModulesCodegen = - (((Writer.WritingModule && - Writer.WritingModule->Kind == Module::ModuleInterfaceUnit) || - Writer.Context->getLangOpts().BuildingPCHWithObjectFile) && + (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit && Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal); } Record.push_back(ModulesCodegen); @@ -1088,8 +1100,6 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { Record.AddStmt(D->getUninstantiatedDefaultArg()); Code = serialization::DECL_PARM_VAR; - assert(!D->isARCPseudoStrong()); // can be true of ImplicitParamDecl - // If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here // we dynamically check for the properties that we optimize for, but don't // know are true of all PARM_VAR_DECLs. @@ -1481,6 +1491,10 @@ void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) { Code = serialization::DECL_CONCEPT; } +void ASTDeclWriter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) { + Code = serialization::DECL_REQUIRES_EXPR_BODY; +} + void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { VisitRedeclarable(D); @@ -1670,6 +1684,8 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { // For an expanded parameter pack, record the number of expansion types here // so that it's easier for deserialization to allocate the right amount of // memory. + Expr *TypeConstraint = D->getPlaceholderTypeConstraint(); + Record.push_back(!!TypeConstraint); if (D->isExpandedParameterPack()) Record.push_back(D->getNumExpansionTypes()); @@ -1677,6 +1693,8 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { // TemplateParmPosition. Record.push_back(D->getDepth()); Record.push_back(D->getPosition()); + if (TypeConstraint) + Record.AddStmt(TypeConstraint); if (D->isExpandedParameterPack()) { for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { @@ -2101,7 +2119,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // SClass Abv->Add(BitCodeAbbrevOp(0)); // TSCSpec Abv->Add(BitCodeAbbrevOp(0)); // InitStyle - Abv->Add(BitCodeAbbrevOp(0)); // ARCPseudoStrong + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong Abv->Add(BitCodeAbbrevOp(0)); // Linkage Abv->Add(BitCodeAbbrevOp(0)); // HasInit Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo @@ -2266,13 +2284,13 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF)); //Stmt - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind //DeclRefExpr @@ -2290,13 +2308,13 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL)); //Stmt - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind //Integer Literal @@ -2309,13 +2327,13 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL)); //Stmt - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind //Character Literal @@ -2328,13 +2346,13 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST)); // Stmt - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind // CastExpr @@ -2414,12 +2432,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { SourceLocation Loc = D->getLocation(); unsigned Index = ID - FirstDeclID; if (DeclOffsets.size() == Index) - DeclOffsets.push_back(DeclOffset(Loc, Offset)); + DeclOffsets.emplace_back(Loc, Offset, DeclTypesBlockStartOffset); else if (DeclOffsets.size() < Index) { // FIXME: Can/should this happen? DeclOffsets.resize(Index+1); DeclOffsets[Index].setLocation(Loc); - DeclOffsets[Index].BitOffset = Offset; + DeclOffsets[Index].setBitOffset(Offset, DeclTypesBlockStartOffset); } else { llvm_unreachable("declarations should be emitted in ID order"); } @@ -2442,9 +2460,8 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { bool ModulesCodegen = false; if (!FD->isDependentContext()) { Optional<GVALinkage> Linkage; - if ((Writer->WritingModule && - Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) || - Writer->Context->getLangOpts().BuildingPCHWithObjectFile) { + if (Writer->WritingModule && + Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) { // When building a C++ Modules TS module interface unit, a strong // definition in the module interface is provided by the compilation of // that module interface unit, not by its users. (Inline functions are diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 9231f3b2b9ba..0767b3a24bf2 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -11,7 +11,9 @@ /// //===----------------------------------------------------------------------===// +#include "clang/AST/ExprOpenMP.h" #include "clang/Serialization/ASTRecordWriter.h" +#include "clang/Sema/DeclSpec.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -67,7 +69,6 @@ void ASTStmtWriter::AddTemplateKWAndArgsInfo( } void ASTStmtWriter::VisitStmt(Stmt *S) { - Record.push_back(S->StmtBits.IsOMPStructuredBlock); } void ASTStmtWriter::VisitNullStmt(NullStmt *S) { @@ -193,6 +194,8 @@ void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) { Record.AddDeclRef(S->getConditionVariable()); Record.AddSourceLocation(S->getWhileLoc()); + Record.AddSourceLocation(S->getLParenLoc()); + Record.AddSourceLocation(S->getRParenLoc()); Code = serialization::STMT_WHILE; } @@ -388,19 +391,9 @@ void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) { Code = serialization::EXPR_DEPENDENT_COAWAIT; } -void ASTStmtWriter::VisitConceptSpecializationExpr( - ConceptSpecializationExpr *E) { - VisitExpr(E); - ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments(); - Record.push_back(TemplateArgs.size()); - Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc()); - Record.AddSourceLocation(E->getTemplateKWLoc()); - Record.AddDeclarationNameInfo(E->getConceptNameInfo()); - Record.AddDeclRef(E->getNamedConcept()); - Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten()); - for (const TemplateArgument &Arg : TemplateArgs) - Record.AddTemplateArgument(Arg); - const ASTConstraintSatisfaction &Satisfaction = E->getSatisfaction(); +static void +addConstraintSatisfaction(ASTRecordWriter &Record, + const ASTConstraintSatisfaction &Satisfaction) { Record.push_back(Satisfaction.IsSatisfied); if (!Satisfaction.IsSatisfied) { Record.push_back(Satisfaction.NumRecords); @@ -418,10 +411,99 @@ void ASTStmtWriter::VisitConceptSpecializationExpr( } } } +} + +static void +addSubstitutionDiagnostic( + ASTRecordWriter &Record, + const concepts::Requirement::SubstitutionDiagnostic *D) { + Record.AddString(D->SubstitutedEntity); + Record.AddSourceLocation(D->DiagLoc); + Record.AddString(D->DiagMessage); +} + +void ASTStmtWriter::VisitConceptSpecializationExpr( + ConceptSpecializationExpr *E) { + VisitExpr(E); + ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments(); + Record.push_back(TemplateArgs.size()); + Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc()); + Record.AddSourceLocation(E->getTemplateKWLoc()); + Record.AddDeclarationNameInfo(E->getConceptNameInfo()); + Record.AddDeclRef(E->getNamedConcept()); + Record.AddDeclRef(E->getFoundDecl()); + Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten()); + for (const TemplateArgument &Arg : TemplateArgs) + Record.AddTemplateArgument(Arg); + if (!E->isValueDependent()) + addConstraintSatisfaction(Record, E->getSatisfaction()); Code = serialization::EXPR_CONCEPT_SPECIALIZATION; } +void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) { + VisitExpr(E); + Record.push_back(E->getLocalParameters().size()); + Record.push_back(E->getRequirements().size()); + Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc); + Record.push_back(E->RequiresExprBits.IsSatisfied); + Record.AddDeclRef(E->getBody()); + for (ParmVarDecl *P : E->getLocalParameters()) + Record.AddDeclRef(P); + for (concepts::Requirement *R : E->getRequirements()) { + if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(R)) { + Record.push_back(concepts::Requirement::RK_Type); + Record.push_back(TypeReq->Status); + if (TypeReq->Status == concepts::TypeRequirement::SS_SubstitutionFailure) + addSubstitutionDiagnostic(Record, TypeReq->getSubstitutionDiagnostic()); + else + Record.AddTypeSourceInfo(TypeReq->getType()); + } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) { + Record.push_back(ExprReq->getKind()); + Record.push_back(ExprReq->Status); + if (ExprReq->isExprSubstitutionFailure()) { + addSubstitutionDiagnostic(Record, + ExprReq->Value.get<concepts::Requirement::SubstitutionDiagnostic *>()); + } else + Record.AddStmt(ExprReq->Value.get<Expr *>()); + if (ExprReq->getKind() == concepts::Requirement::RK_Compound) { + Record.AddSourceLocation(ExprReq->NoexceptLoc); + const auto &RetReq = ExprReq->getReturnTypeRequirement(); + if (RetReq.isSubstitutionFailure()) { + Record.push_back(2); + addSubstitutionDiagnostic(Record, RetReq.getSubstitutionDiagnostic()); + } else if (RetReq.isTypeConstraint()) { + Record.push_back(1); + Record.AddTemplateParameterList( + RetReq.getTypeConstraintTemplateParameterList()); + if (ExprReq->Status >= + concepts::ExprRequirement::SS_ConstraintsNotSatisfied) + Record.AddStmt( + ExprReq->getReturnTypeRequirementSubstitutedConstraintExpr()); + } else { + assert(RetReq.isEmpty()); + Record.push_back(0); + } + } + } else { + auto *NestedReq = cast<concepts::NestedRequirement>(R); + Record.push_back(concepts::Requirement::RK_Nested); + Record.push_back(NestedReq->isSubstitutionFailure()); + if (NestedReq->isSubstitutionFailure()){ + addSubstitutionDiagnostic(Record, + NestedReq->getSubstitutionDiagnostic()); + } else { + Record.AddStmt(NestedReq->Value.get<Expr *>()); + if (!NestedReq->isDependent()) + addConstraintSatisfaction(Record, *NestedReq->Satisfaction); + } + } + } + Record.AddSourceLocation(E->getEndLoc()); + + Code = serialization::EXPR_REQUIRES; +} + void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) { VisitStmt(S); @@ -461,22 +543,34 @@ void ASTStmtWriter::VisitExpr(Expr *E) { Record.push_back(E->isValueDependent()); Record.push_back(E->isInstantiationDependent()); Record.push_back(E->containsUnexpandedParameterPack()); + Record.push_back(E->containsErrors()); Record.push_back(E->getValueKind()); Record.push_back(E->getObjectKind()); } void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) { VisitExpr(E); - Record.push_back(static_cast<uint64_t>(E->ConstantExprBits.ResultKind)); + Record.push_back(E->ConstantExprBits.ResultKind); + + Record.push_back(E->ConstantExprBits.APValueKind); + Record.push_back(E->ConstantExprBits.IsUnsigned); + Record.push_back(E->ConstantExprBits.BitWidth); + // HasCleanup not serialized since we can just query the APValue. + Record.push_back(E->ConstantExprBits.IsImmediateInvocation); + switch (E->ConstantExprBits.ResultKind) { + case ConstantExpr::RSK_None: + break; case ConstantExpr::RSK_Int64: Record.push_back(E->Int64Result()); - Record.push_back(E->ConstantExprBits.IsUnsigned | - E->ConstantExprBits.BitWidth << 1); break; case ConstantExpr::RSK_APValue: Record.AddAPValue(E->APValueResult()); + break; + default: + llvm_unreachable("unexpected ResultKind!"); } + Record.AddStmt(E->getSubExpr()); Code = serialization::EXPR_CONSTANT; } @@ -548,8 +642,9 @@ void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) { void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) { VisitExpr(E); Record.AddSourceLocation(E->getLocation()); + Record.push_back(E->getScale()); Record.AddAPInt(E->getValue()); - Code = serialization::EXPR_INTEGER_LITERAL; + Code = serialization::EXPR_FIXEDPOINT_LITERAL; } void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) { @@ -620,10 +715,16 @@ void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) { void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); + bool HasFPFeatures = E->hasStoredFPFeatures(); + // Write this first for easy access when deserializing, as they affect the + // size of the UnaryOperator. + Record.push_back(HasFPFeatures); Record.AddStmt(E->getSubExpr()); Record.push_back(E->getOpcode()); // FIXME: stable encoding Record.AddSourceLocation(E->getOperatorLoc()); Record.push_back(E->canOverflow()); + if (HasFPFeatures) + Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt()); Code = serialization::EXPR_UNARY_OPERATOR; } @@ -684,16 +785,66 @@ void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { Code = serialization::EXPR_ARRAY_SUBSCRIPT; } +void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) { + VisitExpr(E); + Record.AddStmt(E->getBase()); + Record.AddStmt(E->getRowIdx()); + Record.AddStmt(E->getColumnIdx()); + Record.AddSourceLocation(E->getRBracketLoc()); + Code = serialization::EXPR_ARRAY_SUBSCRIPT; +} + void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { VisitExpr(E); Record.AddStmt(E->getBase()); Record.AddStmt(E->getLowerBound()); Record.AddStmt(E->getLength()); - Record.AddSourceLocation(E->getColonLoc()); + Record.AddStmt(E->getStride()); + Record.AddSourceLocation(E->getColonLocFirst()); + Record.AddSourceLocation(E->getColonLocSecond()); Record.AddSourceLocation(E->getRBracketLoc()); Code = serialization::EXPR_OMP_ARRAY_SECTION; } +void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { + VisitExpr(E); + Record.push_back(E->getDimensions().size()); + Record.AddStmt(E->getBase()); + for (Expr *Dim : E->getDimensions()) + Record.AddStmt(Dim); + for (SourceRange SR : E->getBracketsRanges()) + Record.AddSourceRange(SR); + Record.AddSourceLocation(E->getLParenLoc()); + Record.AddSourceLocation(E->getRParenLoc()); + Code = serialization::EXPR_OMP_ARRAY_SHAPING; +} + +void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) { + VisitExpr(E); + Record.push_back(E->numOfIterators()); + Record.AddSourceLocation(E->getIteratorKwLoc()); + Record.AddSourceLocation(E->getLParenLoc()); + Record.AddSourceLocation(E->getRParenLoc()); + for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { + Record.AddDeclRef(E->getIteratorDecl(I)); + Record.AddSourceLocation(E->getAssignLoc(I)); + OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); + Record.AddStmt(Range.Begin); + Record.AddStmt(Range.End); + Record.AddStmt(Range.Step); + Record.AddSourceLocation(E->getColonLoc(I)); + if (Range.Step) + Record.AddSourceLocation(E->getSecondColonLoc(I)); + // Serialize helpers + OMPIteratorHelperData &HD = E->getHelper(I); + Record.AddDeclRef(HD.CounterVD); + Record.AddStmt(HD.Upper); + Record.AddStmt(HD.Update); + Record.AddStmt(HD.CounterUpdate); + } + Code = serialization::EXPR_OMP_ITERATOR; +} + void ASTStmtWriter::VisitCallExpr(CallExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); @@ -706,6 +857,16 @@ void ASTStmtWriter::VisitCallExpr(CallExpr *E) { Code = serialization::EXPR_CALL; } +void ASTStmtWriter::VisitRecoveryExpr(RecoveryExpr *E) { + VisitExpr(E); + Record.push_back(std::distance(E->children().begin(), E->children().end())); + Record.AddSourceLocation(E->getBeginLoc()); + Record.AddSourceLocation(E->getEndLoc()); + for (Stmt *Child : E->children()) + Record.AddStmt(Child); + Code = serialization::EXPR_RECOVERY; +} + void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { VisitExpr(E); @@ -788,11 +949,16 @@ void ASTStmtWriter::VisitCastExpr(CastExpr *E) { void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) { VisitExpr(E); + bool HasFPFeatures = E->hasStoredFPFeatures(); + // Write this first for easy access when deserializing, as they affect the + // size of the UnaryOperator. + Record.push_back(HasFPFeatures); + Record.push_back(E->getOpcode()); // FIXME: stable encoding Record.AddStmt(E->getLHS()); Record.AddStmt(E->getRHS()); - Record.push_back(E->getOpcode()); // FIXME: stable encoding Record.AddSourceLocation(E->getOperatorLoc()); - Record.push_back(E->getFPFeatures().getInt()); + if (HasFPFeatures) + Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt()); Code = serialization::EXPR_BINARY_OPERATOR; } @@ -989,6 +1155,7 @@ void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) { Record.AddStmt(E->getSubStmt()); Record.AddSourceLocation(E->getLParenLoc()); Record.AddSourceLocation(E->getRParenLoc()); + Record.push_back(E->getTemplateDepth()); Code = serialization::EXPR_STMT; } @@ -1382,8 +1549,8 @@ void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); Record.push_back(E->getOperator()); - Record.push_back(E->getFPFeatures().getInt()); Record.AddSourceRange(E->Range); + Record.push_back(E->getFPFeatures().getAsOpaqueInt()); Code = serialization::EXPR_CXX_OPERATOR_CALL; } @@ -1437,12 +1604,12 @@ void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) { VisitExpr(E); - Record.push_back(E->NumCaptures); + Record.push_back(E->LambdaExprBits.NumCaptures); Record.AddSourceRange(E->IntroducerRange); - Record.push_back(E->CaptureDefault); // FIXME: stable encoding + Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding Record.AddSourceLocation(E->CaptureDefaultLoc); - Record.push_back(E->ExplicitParams); - Record.push_back(E->ExplicitResultType); + Record.push_back(E->LambdaExprBits.ExplicitParams); + Record.push_back(E->LambdaExprBits.ExplicitResultType); Record.AddSourceLocation(E->ClosingBrace); // Add capture initializers. @@ -1452,6 +1619,9 @@ void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) { Record.AddStmt(*C); } + // Don't serialize the body. It belongs to the call operator declaration. + // LambdaExpr only stores a copy of the Stmt *. + Code = serialization::EXPR_LAMBDA; } @@ -1487,6 +1657,11 @@ void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) { Code = serialization::EXPR_CXX_CONST_CAST; } +void ASTStmtWriter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) { + VisitCXXNamedCastExpr(E); + Code = serialization::EXPR_CXX_ADDRSPACE_CAST; +} + void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) { VisitExplicitCastExpr(E); Record.AddSourceLocation(E->getLParenLoc()); @@ -1498,6 +1673,7 @@ void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) { VisitExplicitCastExpr(E); Record.AddSourceLocation(E->getBeginLoc()); Record.AddSourceLocation(E->getEndLoc()); + Code = serialization::EXPR_BUILTIN_BIT_CAST; } void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) { @@ -1641,8 +1817,15 @@ void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) { VisitExpr(E); Record.push_back(E->getNumObjects()); - for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i) - Record.AddDeclRef(E->getObject(i)); + for (auto &Obj : E->getObjects()) { + if (auto *BD = Obj.dyn_cast<BlockDecl *>()) { + Record.push_back(serialization::COK_Block); + Record.AddDeclRef(BD); + } else if (auto *CLE = Obj.dyn_cast<CompoundLiteralExpr *>()) { + Record.push_back(serialization::COK_CompoundLiteral); + Record.AddStmt(CLE); + } + } Record.push_back(E->cleanupsHaveSideEffects()); Record.AddStmt(E->getSubExpr()); @@ -1931,7 +2114,7 @@ void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) { void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) { VisitExpr(E); Record.AddSourceRange(E->getSourceRange()); - Record.AddString(E->getUuidStr()); + Record.AddDeclRef(E->getGuidDecl()); if (E->isTypeOperand()) { Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo()); Code = serialization::EXPR_CXX_UUIDOF_TYPE; @@ -2051,6 +2234,7 @@ void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) { VisitStmt(D); Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE; } @@ -2062,6 +2246,7 @@ void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) { void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) { VisitOMPLoopDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_FOR_DIRECTIVE; } @@ -2075,6 +2260,7 @@ void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) { VisitStmt(D); Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE; } @@ -2109,6 +2295,7 @@ void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) { void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) { VisitOMPLoopDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE; } @@ -2124,6 +2311,7 @@ void ASTStmtWriter::VisitOMPParallelMasterDirective( VisitStmt(D); Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Code = serialization::STMT_OMP_PARALLEL_MASTER_DIRECTIVE; } @@ -2132,6 +2320,7 @@ void ASTStmtWriter::VisitOMPParallelSectionsDirective( VisitStmt(D); Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE; } @@ -2192,12 +2381,15 @@ void ASTStmtWriter::VisitOMPTargetParallelDirective( VisitStmt(D); Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); + Record.writeBool(D->hasCancel()); Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE; } void ASTStmtWriter::VisitOMPTargetParallelForDirective( OMPTargetParallelForDirective *D) { VisitOMPLoopDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE; } @@ -2235,6 +2427,20 @@ void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) { Code = serialization::STMT_OMP_FLUSH_DIRECTIVE; } +void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) { + VisitStmt(D); + Record.push_back(D->getNumClauses()); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) { + VisitStmt(D); + Record.push_back(D->getNumClauses()); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_SCAN_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) { VisitStmt(D); Record.push_back(D->getNumClauses()); @@ -2267,6 +2473,7 @@ void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) { void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) { VisitOMPLoopDirective(D); + Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE; } @@ -2278,6 +2485,7 @@ void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) { void ASTStmtWriter::VisitOMPMasterTaskLoopDirective( OMPMasterTaskLoopDirective *D) { VisitOMPLoopDirective(D); + Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE; } @@ -2290,6 +2498,7 @@ void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective( void ASTStmtWriter::VisitOMPParallelMasterTaskLoopDirective( OMPParallelMasterTaskLoopDirective *D) { VisitOMPLoopDirective(D); + Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE; } @@ -2314,6 +2523,7 @@ void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) { void ASTStmtWriter::VisitOMPDistributeParallelForDirective( OMPDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE; } @@ -2362,6 +2572,7 @@ void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective( void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective( OMPTeamsDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE; } @@ -2382,6 +2593,7 @@ void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective( void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective( OMPTargetTeamsDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + Record.AddStmt(D->getTaskReductionRefExpr()); Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE; } diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp index 002233e49bb0..d869796b82c1 100644 --- a/clang/lib/Serialization/GeneratePCH.cpp +++ b/clang/lib/Serialization/GeneratePCH.cpp @@ -57,6 +57,11 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { } } + // Errors that do not prevent the PCH from being written should not cause the + // overall compilation to fail either. + if (AllowASTWithErrors) + PP.getDiagnostics().getClient()->clear(); + // Emit the PCH file to the Buffer. assert(SemaPtr && "No Sema?"); Buffer->Signature = diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp index 462d29c2a0f1..9192b3b476bb 100644 --- a/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -321,7 +321,7 @@ bool GlobalModuleIndex::lookupIdentifier(StringRef Name, HitSet &Hits) { = *static_cast<IdentifierIndexTable *>(IdentifierIndex); IdentifierIndexTable::iterator Known = Table.find(Name); if (Known == Table.end()) { - return true; + return false; } SmallVector<unsigned, 2> ModuleIDs = *Known; @@ -643,10 +643,10 @@ llvm::Error GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Skip the stored signature. // FIXME: we could read the signature out of the import and validate it. - ASTFileSignature StoredSignature = { - {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++]}}}; + auto FirstSignatureByte = Record.begin() + Idx; + ASTFileSignature StoredSignature = ASTFileSignature::create( + FirstSignatureByte, FirstSignatureByte + ASTFileSignature::size); + Idx += ASTFileSignature::size; // Skip the module name (currently this is only used for prebuilt // modules while here we are only dealing with cached). @@ -704,9 +704,8 @@ llvm::Error GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Get Signature. if (State == DiagnosticOptionsBlock && Code == SIGNATURE) - getModuleFileInfo(File).Signature = { - {{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2], - (uint32_t)Record[3], (uint32_t)Record[4]}}}; + getModuleFileInfo(File).Signature = ASTFileSignature::create( + Record.begin(), Record.begin() + ASTFileSignature::size); // We don't care about this record. } diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index daef502cdcb5..a42ed2f3c179 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -185,7 +185,14 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, Buf = llvm::MemoryBuffer::getSTDIN(); } else { // Get a buffer of the file and close the file descriptor when done. - Buf = FileMgr.getBufferForFile(NewModule->File, /*isVolatile=*/false); + // The file is volatile because in a parallel build we expect multiple + // compiler processes to use the same module file rebuilding it if needed. + // + // RequiresNullTerminator is false because module files don't need it, and + // this allows the file to still be mmapped. + Buf = FileMgr.getBufferForFile(NewModule->File, + /*IsVolatile=*/true, + /*RequiresNullTerminator=*/false); } if (!Buf) { @@ -439,7 +446,7 @@ bool ModuleManager::lookupModuleFile(StringRef FileName, // Open the file immediately to ensure there is no race between stat'ing and // opening the file. - auto FileOrErr = FileMgr.getFile(FileName, /*OpenFile=*/true, + auto FileOrErr = FileMgr.getFile(FileName, /*OpenFile=*/true, /*CacheFailure=*/false); if (!FileOrErr) { File = nullptr; |