diff options
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 723839ff62b..8a02ea93f40 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9254,7 +9254,7 @@ std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) { } void ASTReader::finishPendingActions() { - while (!PendingIdentifierInfos.empty() || + while (!PendingIdentifierInfos.empty() || !PendingFunctionTypes.empty() || !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() || !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() || !PendingUpdateRecords.empty()) { @@ -9273,6 +9273,21 @@ void ASTReader::finishPendingActions() { SetGloballyVisibleDecls(II, DeclIDs, &TopLevelDecls[II]); } + // Load each function type that we deferred loading because it was a + // deduced type that might refer to a local type declared within itself. + for (unsigned I = 0; I != PendingFunctionTypes.size(); ++I) { + auto *FD = PendingFunctionTypes[I].first; + FD->setType(GetType(PendingFunctionTypes[I].second)); + + // If we gave a function a deduced return type, remember that we need to + // propagate that along the redeclaration chain. + auto *DT = FD->getReturnType()->getContainedDeducedType(); + if (DT && DT->isDeduced()) + PendingDeducedTypeUpdates.insert( + {FD->getCanonicalDecl(), FD->getReturnType()}); + } + PendingFunctionTypes.clear(); + // For each decl chain that we wanted to complete while deserializing, mark // it as "still needs to be completed". for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) { @@ -9282,7 +9297,8 @@ void ASTReader::finishPendingActions() { // Load pending declaration chains. for (unsigned I = 0; I != PendingDeclChains.size(); ++I) - loadPendingDeclChain(PendingDeclChains[I].first, PendingDeclChains[I].second); + loadPendingDeclChain(PendingDeclChains[I].first, + PendingDeclChains[I].second); PendingDeclChains.clear(); // Make the most recent of the top-level declarations visible. @@ -11531,11 +11547,16 @@ void ASTReader::FinishedDeserializing() { --NumCurrentElementsDeserializing; if (NumCurrentElementsDeserializing == 0) { - // Propagate exception specification updates along redeclaration chains. - while (!PendingExceptionSpecUpdates.empty()) { - auto Updates = std::move(PendingExceptionSpecUpdates); + // Propagate exception specification and deduced type updates along + // redeclaration chains. + // + // We do this now rather than in finishPendingActions because we want to + // be able to walk the complete redeclaration chains of the updated decls. + while (!PendingExceptionSpecUpdates.empty() || + !PendingDeducedTypeUpdates.empty()) { + auto ESUpdates = std::move(PendingExceptionSpecUpdates); PendingExceptionSpecUpdates.clear(); - for (auto Update : Updates) { + for (auto Update : ESUpdates) { ProcessingUpdatesRAIIObj ProcessingUpdates(*this); auto *FPT = Update.second->getType()->castAs<FunctionProtoType>(); auto ESI = FPT->getExtProtoInfo().ExceptionSpec; @@ -11544,6 +11565,15 @@ void ASTReader::FinishedDeserializing() { for (auto *Redecl : Update.second->redecls()) getContext().adjustExceptionSpec(cast<FunctionDecl>(Redecl), ESI); } + + auto DTUpdates = std::move(PendingDeducedTypeUpdates); + PendingDeducedTypeUpdates.clear(); + for (auto Update : DTUpdates) { + ProcessingUpdatesRAIIObj ProcessingUpdates(*this); + // FIXME: If the return type is already deduced, check that it matches. + getContext().adjustDeducedFunctionResultType(Update.first, + Update.second); + } } if (ReadTimer) |