diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-04-24 16:28:06 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-04-24 16:28:06 +0000 |
commit | 58a2cd8c0d52e710cbcc57a67eac7b51b0b831c4 (patch) | |
tree | 5a90a0576e259fe137f4af70496cc2cc0e980958 /lib | |
parent | 024e1c400ec1d23dd76659395f87272da59a2cbd (diff) |
Synthesizing the definition of an implicit member is an AST modification, so notify any mutation listeners of it. This fixes a crasher in chained PCH, where an implicit destructor in a PCH gets a definition in a chained PCH, which is then lost. However, any further use of the destructor would cause its definition to be regenerated in the final file, hiding the bug.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130103 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Frontend/MultiplexConsumer.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 17 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 9 |
4 files changed, 36 insertions, 0 deletions
diff --git a/lib/Frontend/MultiplexConsumer.cpp b/lib/Frontend/MultiplexConsumer.cpp index ecad91f1f0..721bd05a98 100644 --- a/lib/Frontend/MultiplexConsumer.cpp +++ b/lib/Frontend/MultiplexConsumer.cpp @@ -97,6 +97,7 @@ public: const ClassTemplateSpecializationDecl *D); virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, const FunctionDecl *D); + virtual void CompletedImplicitDefinition(const FunctionDecl *D); private: std::vector<ASTMutationListener*> Listeners; }; @@ -132,6 +133,11 @@ void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->AddedCXXTemplateSpecialization(TD, D); } +void MultiplexASTMutationListener::CompletedImplicitDefinition( + const FunctionDecl *D) { + for (size_t i = 0, e = Listeners.size(); i != e; ++i) + Listeners[i]->CompletedImplicitDefinition(D); +} } // end namespace clang diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index c954c64e7d..3ce1d82c88 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -201,6 +201,10 @@ Sema::~Sema() { ExternalSema->ForgetSema(); } +ASTMutationListener *Sema::getASTMutationListener() const { + return getASTConsumer().GetASTMutationListener(); +} + /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast. /// If there is already an implicit cast, merge into the existing one. /// The result is of the given category. diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3a87cfd966..bd4aac8985 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -18,6 +18,7 @@ #include "clang/Sema/Lookup.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTMutationListener.h" #include "clang/AST/CharUnits.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclVisitor.h" @@ -4969,6 +4970,10 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, Constructor->setUsed(); MarkVTableUsed(CurrentLocation, ClassDecl); + + if (ASTMutationListener *L = getASTMutationListener()) { + L->CompletedImplicitDefinition(Constructor); + } } void Sema::DeclareInheritedConstructors(CXXRecordDecl *ClassDecl) { @@ -5254,6 +5259,10 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, Destructor->setUsed(); MarkVTableUsed(CurrentLocation, ClassDecl); + + if (ASTMutationListener *L = getASTMutationListener()) { + L->CompletedImplicitDefinition(Destructor); + } } /// \brief Builds a statement that copies the given entity from \p From to @@ -5913,6 +5922,10 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, /*isStmtExpr=*/false); assert(!Body.isInvalid() && "Compound statement creation cannot fail"); CopyAssignOperator->setBody(Body.takeAs<Stmt>()); + + if (ASTMutationListener *L = getASTMutationListener()) { + L->CompletedImplicitDefinition(CopyAssignOperator); + } } CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( @@ -6113,6 +6126,10 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, } CopyConstructor->setUsed(); + + if (ASTMutationListener *L = getASTMutationListener()) { + L->CompletedImplicitDefinition(CopyConstructor); + } } ExprResult diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index fb193651b8..42393dea2b 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -3955,4 +3955,13 @@ void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, AddDeclRef(D, Record); } +void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { + if (D->getPCHLevel() == 0) + return; // Declaration not imported from PCH. + + // Implicit decl from a PCH was defined. + // FIXME: Should implicit definition be a separate FunctionDecl? + RewriteDecl(D); +} + ASTSerializationListener::~ASTSerializationListener() { } |