diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index c92e6dde2802..961f49b871c0 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -389,7 +389,9 @@ public: } bool hasAttrs() const { return HasAttrs; } - void setAttrs(const AttrVec& Attrs); + void setAttrs(const AttrVec& Attrs) { + return setAttrsImpl(Attrs, getASTContext()); + } AttrVec &getAttrs() { return const_cast(const_cast(this)->getAttrs()); } @@ -852,6 +854,9 @@ public: private: const Attr *getAttrsImpl() const; + void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); + void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, + ASTContext &Ctx); protected: ASTMutationListener *getASTMutationListener() const; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index da54a44784e2..a507215aa843 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -203,15 +203,24 @@ void Decl::setLexicalDeclContext(DeclContext *DC) { return; if (isInSemaDC()) { - MultipleDC *MDC = new (getASTContext()) MultipleDC(); - MDC->SemanticDC = getDeclContext(); - MDC->LexicalDC = DC; - DeclCtx = MDC; + setDeclContextsImpl(getDeclContext(), DC, getASTContext()); } else { getMultipleDC()->LexicalDC = DC; } } +void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, + ASTContext &Ctx) { + if (SemaDC == LexicalDC) { + DeclCtx = SemaDC; + } else { + Decl::MultipleDC *MDC = new (Ctx) Decl::MultipleDC(); + MDC->SemanticDC = SemaDC; + MDC->LexicalDC = LexicalDC; + DeclCtx = MDC; + } +} + bool Decl::isInAnonymousNamespace() const { const DeclContext *DC = getDeclContext(); do { @@ -532,10 +541,10 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { llvm_unreachable("Invalid DeclKind!"); } -void Decl::setAttrs(const AttrVec &attrs) { +void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) { assert(!HasAttrs && "Decl already contains attrs."); - AttrVec &AttrBlank = getASTContext().getDeclAttrs(this); + AttrVec &AttrBlank = Ctx.getDeclAttrs(this); assert(AttrBlank.empty() && "HasAttrs was wrong?"); AttrBlank = attrs; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index fbe861d6cc3c..690c81ce5303 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -324,12 +324,11 @@ void ASTDeclReader::Visit(Decl *D) { } else if (D->isTemplateParameter()) { // If we have a fully initialized template parameter, we can now // set its DeclContext. - D->setDeclContext( - cast_or_null( - Reader.GetDecl(DeclContextIDForTemplateParmDecl))); - D->setLexicalDeclContext( - cast_or_null( - Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl))); + DeclContext *SemaDC = cast( + Reader.GetDecl(DeclContextIDForTemplateParmDecl)); + DeclContext *LexicalDC = cast( + Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl)); + D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext()); } } @@ -343,15 +342,16 @@ void ASTDeclReader::VisitDecl(Decl *D) { LexicalDeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx); D->setDeclContext(Reader.getContext().getTranslationUnitDecl()); } else { - D->setDeclContext(ReadDeclAs(Record, Idx)); - D->setLexicalDeclContext(ReadDeclAs(Record, Idx)); + DeclContext *SemaDC = ReadDeclAs(Record, Idx); + DeclContext *LexicalDC = ReadDeclAs(Record, Idx); + D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext()); } D->setLocation(Reader.ReadSourceLocation(F, RawLocation)); D->setInvalidDecl(Record[Idx++]); if (Record[Idx++]) { // hasAttrs AttrVec Attrs; Reader.ReadAttributes(F, Attrs, Record, Idx); - D->setAttrs(Attrs); + D->setAttrsImpl(Attrs, Reader.getContext()); } D->setImplicit(Record[Idx++]); D->setUsed(Record[Idx++]);