Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -185,6 +185,10 @@ ASTContext&> SubstTemplateTemplateParmPacks; + /// Generation number for this external AST source. Must be increased + /// whenever we might have added new redeclarations for existing decls. + uint32_t CurrentGeneration = 0; + /// \brief The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. @@ -607,6 +611,15 @@ DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node); + uint32_t getGeneration() const { return CurrentGeneration; } + uint32_t incrementGeneration() { + uint32_t OldGeneration = CurrentGeneration; + CurrentGeneration++; + assert(CurrentGeneration > OldGeneration && + "Overflowed generation counter"); + return OldGeneration; + } + const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; } @@ -2884,7 +2897,7 @@ // include ASTContext.h. We explicitly instantiate it for all relevant types // in ASTContext.cpp. if (auto *Source = Ctx.getExternalSource()) - return new (Ctx) LazyData(Source, Value); + return new (Ctx) LazyData(&Ctx, Source, Value); return Value; } Index: include/clang/AST/ExternalASTSource.h =================================================================== --- include/clang/AST/ExternalASTSource.h +++ include/clang/AST/ExternalASTSource.h @@ -42,9 +42,6 @@ /// actual type and declaration nodes, and read parts of declaration /// contexts. class ExternalASTSource : public RefCountedBase { - /// Generation number for this external AST source. Must be increased - /// whenever we might have added new redeclarations for existing decls. - uint32_t CurrentGeneration; /// \brief Whether this AST source also provides information for /// semantic analysis. @@ -53,7 +50,7 @@ friend class ExternalSemaSource; public: - ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { } + ExternalASTSource() : SemaSource(false) {} virtual ~ExternalASTSource(); @@ -74,7 +71,7 @@ /// \brief Get the current generation of this AST source. This number /// is incremented each time the AST source lazily extends an existing /// entity. - uint32_t getGeneration() const { return CurrentGeneration; } + virtual uint32_t getGeneration(const ASTContext &C) const; /// \brief Resolve a declaration ID into a declaration, potentially /// building a new declaration. @@ -392,8 +389,10 @@ /// A cache of the value of this pointer, in the most recent generation in /// which we queried it. struct LazyData { - LazyData(ExternalASTSource *Source, T Value) - : ExternalSource(Source), LastGeneration(0), LastValue(Value) {} + LazyData(const ASTContext *Context, ExternalASTSource *Source, T Value) + : Context(Context), ExternalSource(Source), LastGeneration(0), + LastValue(Value) {} + const ASTContext *Context; ExternalASTSource *ExternalSource; uint32_t LastGeneration; T LastValue; @@ -438,8 +437,10 @@ /// Get the value of this pointer, updating its owner if necessary. T get(Owner O) { if (LazyData *LazyVal = Value.template dyn_cast()) { - if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) { - LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration(); + if (LazyVal->LastGeneration != + LazyVal->ExternalSource->getGeneration(*LazyVal->Context)) { + LazyVal->LastGeneration = + LazyVal->ExternalSource->getGeneration(*LazyVal->Context); (LazyVal->ExternalSource->*Update)(O); } return LazyVal->LastValue; Index: include/clang/Serialization/ASTReader.h =================================================================== --- include/clang/Serialization/ASTReader.h +++ include/clang/Serialization/ASTReader.h @@ -1208,6 +1208,12 @@ : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) { } }; + uint32_t getGenerationOrNull() const { + if (ContextObj) + return getGeneration(*ContextObj); + return 0u; + } + ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, ModuleFile *ImportedBy, SmallVectorImpl &Loaded, Index: lib/AST/ExternalASTSource.cpp =================================================================== --- lib/AST/ExternalASTSource.cpp +++ lib/AST/ExternalASTSource.cpp @@ -23,6 +23,10 @@ ExternalASTSource::~ExternalASTSource() { } +uint32_t ExternalASTSource::getGeneration(const ASTContext &C) const { + return C.getGeneration(); +} + llvm::Optional ExternalASTSource::getSourceDescriptor(unsigned ID) { return None; @@ -117,19 +121,5 @@ void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {} uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) { - uint32_t OldGeneration = CurrentGeneration; - - // Make sure the generation of the topmost external source for the context is - // incremented. That might not be us. - auto *P = C.getExternalSource(); - if (P && P != this) - CurrentGeneration = P->incrementGeneration(C); - else { - // FIXME: Only bump the generation counter if the current generation number - // has been observed? - if (!++CurrentGeneration) - llvm::report_fatal_error("generation counter overflowed", false); - } - - return OldGeneration; + return C.incrementGeneration(); } Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -1893,7 +1893,7 @@ // Update the generation for this identifier. if (getContext().getLangOpts().Modules) - IdentifierGeneration[II] = getGeneration(); + IdentifierGeneration[II] = getGenerationOrNull(); } void ASTReader::resolvePendingMacro(IdentifierInfo *II, @@ -4057,11 +4057,10 @@ unsigned ClientLoadCapabilities) { ModuleFile *M; std::string ErrorStr; - ModuleManager::AddModuleResult AddResult - = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy, - getGeneration(), ExpectedSize, ExpectedModTime, - ExpectedSignature, readASTFileSignature, - M, ErrorStr); + ModuleManager::AddModuleResult AddResult = + ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy, + getGenerationOrNull(), ExpectedSize, ExpectedModTime, + ExpectedSignature, readASTFileSignature, M, ErrorStr); switch (AddResult) { case ModuleManager::AlreadyLoaded: @@ -7884,7 +7883,7 @@ // Get the selector generation and update it to the current generation. unsigned &Generation = SelectorGeneration[Sel]; unsigned PriorGeneration = Generation; - Generation = getGeneration(); + Generation = getGenerationOrNull(); SelectorOutOfDate[Sel] = false; // Search for methods defined with this selector.