From: Vince Harron Date: Sun, 22 Mar 2015 08:47:07 +0000 (+0000) Subject: Reverting 232853 and 232870 because they depend on 232793, X-Git-Tag: llvmorg-3.7.0-rc1~8643 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=08dcf60295b79ac6a79ac94933778001eab2d389;p=platform%2Fupstream%2Fllvm.git Reverting 232853 and 232870 because they depend on 232793, which was reverted because it was causing LLDB test failures llvm-svn: 232907 --- diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index c631059..55fe0ef 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -446,12 +446,6 @@ private: /// that we needed but hadn't loaded yet. llvm::DenseMap PendingFakeDefinitionData; - /// \brief Exception specification updates that have been loaded but not yet - /// propagated across the relevant redeclaration chain. The map key is the - /// canonical declaration (used only for deduplication) and the value is a - /// declaration that has an exception specification. - llvm::SmallMapVector PendingExceptionSpecUpdates; - struct ReplacedDeclInfo { ModuleFile *Mod; uint64_t Offset; @@ -954,11 +948,6 @@ private: llvm::MapVector > PendingIdentifierInfos; - /// \brief The set of lookup results that we have faked in order to support - /// merging of partially deserialized decls but that we have not yet removed. - llvm::SmallMapVector, 16> - PendingFakeLookupResults; - /// \brief The generation number of each identifier, which keeps track of /// the last time we loaded information about this identifier. llvm::DenseMap IdentifierGeneration; @@ -1185,18 +1174,6 @@ private: /// merged into its redecl chain. Decl *getMostRecentExistingDecl(Decl *D); - template - void forEachFormerlyCanonicalImportedDecl(const Decl *D, Fn Visit) { - D = D->getCanonicalDecl(); - if (D->isFromASTFile()) - Visit(D); - - auto It = MergedDecls.find(const_cast(D)); - if (It != MergedDecls.end()) - for (auto ID : It->second) - Visit(GetExistingDecl(ID)); - } - RecordLocation DeclCursorForID(serialization::DeclID ID, unsigned &RawLocation); void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 51d6ace..41abd49 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -167,13 +167,13 @@ Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { void Sema::UpdateExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI) { + for (auto *Redecl : FD->redecls()) + Context.adjustExceptionSpec(cast(Redecl), ESI); + // If we've fully resolved the exception specification, notify listeners. if (!isUnresolvedExceptionSpec(ESI.Type)) if (auto *Listener = getASTMutationListener()) Listener->ResolvedExceptionSpec(FD); - - for (auto *Redecl : FD->redecls()) - Context.adjustExceptionSpec(cast(Redecl), ESI); } /// Determine whether a function has an implicitly-generated exception diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 55fd600..f4b4c4b 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1,4 +1,4 @@ -//===-- ASTReader.cpp - AST File Reader ----------------------------------===// +//===--- ASTReader.cpp - AST File Reader ----------------------------------===// // // The LLVM Compiler Infrastructure // @@ -8618,13 +8618,6 @@ void ASTReader::FinishedDeserializing() { --NumCurrentElementsDeserializing; if (NumCurrentElementsDeserializing == 0) { - // Propagate exception specification updates along redeclaration chains. - for (auto Update : PendingExceptionSpecUpdates) { - auto *FPT = Update.second->getType()->castAs(); - SemaObj->UpdateExceptionSpec(Update.second, - FPT->getExtProtoInfo().ExceptionSpec); - } - diagnoseOdrViolations(); // We are not in recursive loading, so it's safe to pass the "interesting" @@ -8635,15 +8628,7 @@ void ASTReader::FinishedDeserializing() { } void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { - if (IdentifierInfo *II = Name.getAsIdentifierInfo()) { - // Remove any fake results before adding any real ones. - auto It = PendingFakeLookupResults.find(II); - if (It != PendingFakeLookupResults.end()) { - for (auto *ND : PendingFakeLookupResults[II]) - SemaObj->IdResolver.RemoveDecl(ND); - PendingFakeLookupResults.erase(It); - } - } + D = D->getMostRecentDecl(); if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) { SemaObj->TUScope->AddDecl(D); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 5c6820f..83882a8 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -228,11 +228,9 @@ namespace clang { template static void attachPreviousDeclImpl(ASTReader &Reader, - Redeclarable *D, Decl *Previous, - Decl *Canon); + Redeclarable *D, Decl *Previous); static void attachPreviousDeclImpl(ASTReader &Reader, ...); - static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous, - Decl *Canon); + static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous); template static void attachLatestDeclImpl(Redeclarable *D, Decl *Latest); @@ -2623,11 +2621,8 @@ ASTDeclReader::FindExistingResult::~FindExistingResult() { if (needsAnonymousDeclarationNumber(New)) { setAnonymousDeclForMerging(Reader, New->getLexicalDeclContext(), AnonymousDeclNumber, New); - } else if (DC->isTranslationUnit() && Reader.SemaObj && - !Reader.getContext().getLangOpts().CPlusPlus) { - if (Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, Name)) - Reader.PendingFakeLookupResults[Name.getAsIdentifierInfo()] - .push_back(New); + } else if (DC->isTranslationUnit() && Reader.SemaObj) { + Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, Name); } else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) { // Add the declaration to its redeclaration context so later merging // lookups will find it. @@ -2732,8 +2727,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { if (isSameEntity(Existing, D)) return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, TypedefNameForLinkage); - } else if (DC->isTranslationUnit() && Reader.SemaObj && - !Reader.getContext().getLangOpts().CPlusPlus) { + } else if (DC->isTranslationUnit() && Reader.SemaObj) { IdentifierResolver &IdResolver = Reader.SemaObj->IdResolver; // Temporarily consider the identifier to be up-to-date. We don't want to @@ -2822,14 +2816,14 @@ Decl *ASTReader::getMostRecentExistingDecl(Decl *D) { template void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable *D, - Decl *Previous, Decl *Canon) { + Decl *Previous) { D->RedeclLink.setPrevious(cast(Previous)); } namespace clang { template<> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable *D, - Decl *Previous, Decl *Canon) { + Decl *Previous) { FunctionDecl *FD = static_cast(D); FunctionDecl *PrevFD = cast(Previous); @@ -2856,17 +2850,25 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, FD->IsInline = true; } - // If we need to propagate an exception specification along the redecl - // chain, make a note of that so that we can do so later. + // If this declaration has an unresolved exception specification but the + // previous declaration had a resolved one, resolve the exception + // specification now. If this declaration has a resolved exception + // specification but the previous declarations did not, apply our exception + // specification to all prior ones now. auto *FPT = FD->getType()->getAs(); auto *PrevFPT = PrevFD->getType()->getAs(); if (FPT && PrevFPT) { - bool IsUnresolved = isUnresolvedExceptionSpec(FPT->getExceptionSpecType()); - bool WasUnresolved = - isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType()); - if (IsUnresolved != WasUnresolved) - Reader.PendingExceptionSpecUpdates.insert( - std::make_pair(Canon, IsUnresolved ? PrevFD : FD)); + bool WasUnresolved = isUnresolvedExceptionSpec(FPT->getExceptionSpecType()); + bool IsUnresolved = isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType()); + if (WasUnresolved && !IsUnresolved) { + Reader.Context.adjustExceptionSpec( + FD, PrevFPT->getExtProtoInfo().ExceptionSpec); + } else if (!WasUnresolved && IsUnresolved) { + FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); + for (FunctionDecl *PrevFDToUpdate = PrevFD; PrevFDToUpdate; + PrevFDToUpdate = PrevFDToUpdate->getPreviousDecl()) + Reader.Context.adjustExceptionSpec(PrevFDToUpdate, EPI.ExceptionSpec); + } } } } @@ -2875,14 +2877,14 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) { } void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D, - Decl *Previous, Decl *Canon) { + Decl *Previous) { assert(D && Previous); switch (D->getKind()) { #define ABSTRACT_DECL(TYPE) -#define DECL(TYPE, BASE) \ - case Decl::TYPE: \ - attachPreviousDeclImpl(Reader, cast(D), Previous, Canon); \ +#define DECL(TYPE, BASE) \ + case Decl::TYPE: \ + attachPreviousDeclImpl(Reader, cast(D), Previous); \ break; #include "clang/AST/DeclNodes.inc" } @@ -3386,7 +3388,7 @@ void ASTReader::loadPendingDeclChain(Decl *CanonDecl) { if (Chain[I] == CanonDecl) continue; - ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent, CanonDecl); + ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent); MostRecent = Chain[I]; } ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent); @@ -3730,24 +3732,23 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, } case UPD_CXX_RESOLVED_EXCEPTION_SPEC: { + // FIXME: This doesn't send the right notifications if there are + // ASTMutationListeners other than an ASTWriter. FunctionProtoType::ExceptionSpecInfo ESI; SmallVector ExceptionStorage; Reader.readExceptionSpec(ModuleFile, ExceptionStorage, ESI, Record, Idx); - - // Update this declaration's exception specification, if needed. - auto *FD = cast(D); - auto *FPT = FD->getType()->castAs(); - // FIXME: If the exception specification is already present, check that it - // matches. - if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { + for (auto *Redecl : merged_redecls(D)) { + auto *FD = cast(Redecl); + auto *FPT = FD->getType()->castAs(); + if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { + // AST invariant: if any exception spec in the redecl chain is + // resolved, all are resolved. We don't need to go any further. + // FIXME: If the exception spec is resolved, check that it matches. + break; + } FD->setType(Reader.Context.getFunctionType( FPT->getReturnType(), FPT->getParamTypes(), FPT->getExtProtoInfo().withExceptionSpec(ESI))); - - // When we get to the end of deserializing, see if there are other decls - // that we need to propagate this exception specification onto. - Reader.PendingExceptionSpecUpdates.insert( - std::make_pair(FD->getCanonicalDecl(), FD)); } break; } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index a1fadb2..a8e92b8 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5804,36 +5804,37 @@ void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, } void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) { - assert(!DoneWritingDeclsAndTypes && "Already done writing updates!"); - if (!Chain) return; - Chain->forEachFormerlyCanonicalImportedDecl(FD, [&](const Decl *D) { - // If we don't already know the exception specification for this redecl - // chain, add an update record for it. - if (isUnresolvedExceptionSpec(cast(D) - ->getType() - ->castAs() - ->getExceptionSpecType())) - DeclUpdates[D].push_back(UPD_CXX_RESOLVED_EXCEPTION_SPEC); - }); + assert(!WritingAST && "Already writing the AST!"); + FD = FD->getCanonicalDecl(); + if (!FD->isFromASTFile()) + return; // Not a function declared in PCH and defined outside. + + DeclUpdates[FD].push_back(UPD_CXX_RESOLVED_EXCEPTION_SPEC); } void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { assert(!WritingAST && "Already writing the AST!"); - if (!Chain) return; - Chain->forEachFormerlyCanonicalImportedDecl(FD, [&](const Decl *D) { - DeclUpdates[D].push_back( - DeclUpdate(UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType)); - }); + FD = FD->getCanonicalDecl(); + if (!FD->isFromASTFile()) + return; // Not a function declared in PCH and defined outside. + + DeclUpdates[FD].push_back(DeclUpdate(UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType)); } void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD, const FunctionDecl *Delete) { assert(!WritingAST && "Already writing the AST!"); assert(Delete && "Not given an operator delete"); - if (!Chain) return; - Chain->forEachFormerlyCanonicalImportedDecl(DD, [&](const Decl *D) { - DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_RESOLVED_DTOR_DELETE, Delete)); - }); + for (auto *D : DD->redecls()) { + if (D->isFromASTFile()) { + // We added an operator delete that some imported destructor didn't + // know about. Add an update record to let importers of us and that + // declaration know about it. + DeclUpdates[DD].push_back( + DeclUpdate(UPD_CXX_RESOLVED_DTOR_DELETE, Delete)); + return; + } + } } void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { @@ -5850,7 +5851,8 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) { if (!D->isFromASTFile()) return; - DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION)); + DeclUpdates[D].push_back( + DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION)); } void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { diff --git a/clang/test/Modules/Inputs/update-exception-spec/a.h b/clang/test/Modules/Inputs/update-exception-spec/a.h index 078ebf9..e69de29 100644 --- a/clang/test/Modules/Inputs/update-exception-spec/a.h +++ b/clang/test/Modules/Inputs/update-exception-spec/a.h @@ -1,2 +0,0 @@ -struct A { ~A() throw(int); }; -struct B { A a; }; diff --git a/clang/test/Modules/Inputs/update-exception-spec/b.h b/clang/test/Modules/Inputs/update-exception-spec/b.h index f75b559..e69de29 100644 --- a/clang/test/Modules/Inputs/update-exception-spec/b.h +++ b/clang/test/Modules/Inputs/update-exception-spec/b.h @@ -1,3 +0,0 @@ -struct A { ~A() throw(int); }; -struct B { A a; }; -inline void f(B *p) { p->~B(); } diff --git a/clang/test/Modules/Inputs/update-exception-spec/c.h b/clang/test/Modules/Inputs/update-exception-spec/c.h index 067dbb6..e69de29 100644 --- a/clang/test/Modules/Inputs/update-exception-spec/c.h +++ b/clang/test/Modules/Inputs/update-exception-spec/c.h @@ -1,3 +0,0 @@ -#include "a.h" -#include "b.h" -inline void g(B *p) { p->~B(); } diff --git a/clang/test/Modules/Inputs/update-exception-spec/module.modulemap b/clang/test/Modules/Inputs/update-exception-spec/module.modulemap index 880ae38..e69de29 100644 --- a/clang/test/Modules/Inputs/update-exception-spec/module.modulemap +++ b/clang/test/Modules/Inputs/update-exception-spec/module.modulemap @@ -1,3 +0,0 @@ -module a { header "a.h" } -module b { header "b.h" } -module c { header "c.h" } diff --git a/clang/test/Modules/linkage-merge.cpp b/clang/test/Modules/linkage-merge.cpp index 3ac8053..9991789 100644 --- a/clang/test/Modules/linkage-merge.cpp +++ b/clang/test/Modules/linkage-merge.cpp @@ -11,5 +11,6 @@ static void g(int); // happen to find lookup results for 'g'; LookupResult::resolveKind needs to // be taught to prefer a visible result over a non-visible one. // -// expected-error@9 {{functions that differ only in their return type cannot be overloaded}} -// expected-note@Inputs/linkage-merge-foo.h:2 {{previous declaration is here}} +// FIXME-error@-1 {{functions that differ only in their return type cannot be overloaded}} +// FIXME-note@Inputs/linkage-merge-foo.h:2 {{previous declaration is here}} +// expected-no-diagnostics diff --git a/clang/test/Modules/update-exception-spec.cpp b/clang/test/Modules/update-exception-spec.cpp index bccdddc..e69de29 100644 --- a/clang/test/Modules/update-exception-spec.cpp +++ b/clang/test/Modules/update-exception-spec.cpp @@ -1,6 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fmodules -fmodules-cache-path=%t -I%S/Inputs/update-exception-spec -emit-llvm-only %s -#include "a.h" -void use(B *p); -#include "c.h" -void use(B *p) { g(p); }