Hi Richard, There is an internal-for-testing clang option ‘-error-on-deserialized-decl’ intended for testing that we haven’t deserialized something unnecessarily, would it be applicable to be used for your recent changes along with the appropriate test cases ?
> On Mar 23, 2015, at 11:36 PM, Richard Smith <[email protected]> > wrote: > > Author: rsmith > Date: Tue Mar 24 01:36:48 2015 > New Revision: 233052 > > URL: http://llvm.org/viewvc/llvm-project?rev=233052&view=rev > Log: > [modules] Deserialize CXXCtorInitializer list for a constructor lazily. > > Previously we'd deserialize the list of mem-initializers for a constructor > when > we deserialized the declaration of the constructor. That could trigger a > significant amount of unnecessary work (pulling in all base classes > recursively, for a start) and was causing problems for the modules buildbot > due > to cyclic deserializations. We now deserialize these on demand. > > This creates a certain amount of duplication with the handling of > CXXBaseSpecifiers; I'll look into reducing that next. > > Modified: > cfe/trunk/include/clang/AST/DeclCXX.h > cfe/trunk/include/clang/AST/DeclObjC.h > cfe/trunk/include/clang/AST/ExternalASTSource.h > cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h > cfe/trunk/include/clang/Serialization/ASTBitCodes.h > cfe/trunk/include/clang/Serialization/ASTReader.h > cfe/trunk/include/clang/Serialization/ASTWriter.h > cfe/trunk/include/clang/Serialization/Module.h > cfe/trunk/lib/AST/DeclCXX.cpp > cfe/trunk/lib/AST/DeclObjC.cpp > cfe/trunk/lib/AST/ExternalASTSource.cpp > cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp > cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp > cfe/trunk/lib/Serialization/ASTReader.cpp > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > cfe/trunk/lib/Serialization/Module.cpp > > Modified: cfe/trunk/include/clang/AST/DeclCXX.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclCXX.h (original) > +++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Mar 24 01:36:48 2015 > @@ -2149,7 +2149,7 @@ class CXXConstructorDecl : public CXXMet > /// \name Support for base and member initializers. > /// \{ > /// \brief The arguments used to initialize the base or member. > - CXXCtorInitializer **CtorInitializers; > + LazyCXXCtorInitializersPtr CtorInitializers; > unsigned NumCtorInitializers; > /// \} > > @@ -2188,7 +2188,7 @@ public: > typedef CXXCtorInitializer **init_iterator; > > /// \brief Iterates through the member/base initializer list. > - typedef CXXCtorInitializer * const * init_const_iterator; > + typedef CXXCtorInitializer *const *init_const_iterator; > > typedef llvm::iterator_range<init_iterator> init_range; > typedef llvm::iterator_range<init_const_iterator> init_const_range; > @@ -2199,17 +2199,20 @@ public: > } > > /// \brief Retrieve an iterator to the first initializer. > - init_iterator init_begin() { return CtorInitializers; } > + init_iterator init_begin() { > + const auto *ConstThis = this; > + return const_cast<init_iterator>(ConstThis->init_begin()); > + } > /// \brief Retrieve an iterator to the first initializer. > - init_const_iterator init_begin() const { return CtorInitializers; } > + init_const_iterator init_begin() const; > > /// \brief Retrieve an iterator past the last initializer. > init_iterator init_end() { > - return CtorInitializers + NumCtorInitializers; > + return init_begin() + NumCtorInitializers; > } > /// \brief Retrieve an iterator past the last initializer. > init_const_iterator init_end() const { > - return CtorInitializers + NumCtorInitializers; > + return init_begin() + NumCtorInitializers; > } > > typedef std::reverse_iterator<init_iterator> init_reverse_iterator; > @@ -2240,14 +2243,14 @@ public: > NumCtorInitializers = numCtorInitializers; > } > > - void setCtorInitializers(CXXCtorInitializer ** initializers) { > - CtorInitializers = initializers; > + void setCtorInitializers(CXXCtorInitializer **Initializers) { > + CtorInitializers = Initializers; > } > > /// \brief Determine whether this constructor is a delegating constructor. > bool isDelegatingConstructor() const { > return (getNumCtorInitializers() == 1) && > - CtorInitializers[0]->isDelegatingInitializer(); > + init_begin()[0]->isDelegatingInitializer(); > } > > /// \brief When this constructor delegates to another, retrieve the target. > > Modified: cfe/trunk/include/clang/AST/DeclObjC.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclObjC.h (original) > +++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Mar 24 01:36:48 2015 > @@ -2002,8 +2002,8 @@ class ObjCImplementationDecl : public Ob > SourceLocation IvarRBraceLoc; > > /// Support for ivar initialization. > - /// IvarInitializers - The arguments used to initialize the ivars > - CXXCtorInitializer **IvarInitializers; > + /// \brief The arguments used to initialize the ivars > + LazyCXXCtorInitializersPtr IvarInitializers; > unsigned NumIvarInitializers; > > /// Do the ivars of this class require initialization other than > @@ -2052,17 +2052,20 @@ public: > } > > /// init_begin() - Retrieve an iterator to the first initializer. > - init_iterator init_begin() { return IvarInitializers; } > + init_iterator init_begin() { > + const auto *ConstThis = this; > + return const_cast<init_iterator>(ConstThis->init_begin()); > + } > /// begin() - Retrieve an iterator to the first initializer. > - init_const_iterator init_begin() const { return IvarInitializers; } > + init_const_iterator init_begin() const; > > /// init_end() - Retrieve an iterator past the last initializer. > init_iterator init_end() { > - return IvarInitializers + NumIvarInitializers; > + return init_begin() + NumIvarInitializers; > } > /// end() - Retrieve an iterator past the last initializer. > init_const_iterator init_end() const { > - return IvarInitializers + NumIvarInitializers; > + return init_begin() + NumIvarInitializers; > } > /// getNumArgs - Number of ivars which must be initialized. > unsigned getNumIvarInitializers() const { > > Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/ExternalASTSource.h (original) > +++ cfe/trunk/include/clang/AST/ExternalASTSource.h Tue Mar 24 01:36:48 2015 > @@ -22,6 +22,7 @@ namespace clang { > > class ASTConsumer; > class CXXBaseSpecifier; > +class CXXCtorInitializer; > class DeclarationName; > class ExternalSemaSource; // layering violation required for downcasting > class FieldDecl; > @@ -121,6 +122,12 @@ public: > /// The default implementation of this method is a no-op. > virtual Stmt *GetExternalDeclStmt(uint64_t Offset); > > + /// \brief Resolve the offset of a set of C++ constructor initializers in > + /// the decl stream into an array of initializers. > + /// > + /// The default implementation of this method is a no-op. > + virtual CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t > Offset); > + > /// \brief Resolve the offset of a set of C++ base specifiers in the decl > /// stream into an array of specifiers. > /// > @@ -553,8 +560,13 @@ typedef LazyOffsetPtr<Stmt, uint64_t, &E > typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl> > LazyDeclPtr; > > +/// \brief A lazy pointer to a set of CXXCtorInitializers. > +typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t, > + &ExternalASTSource::GetExternalCXXCtorInitializers> > + LazyCXXCtorInitializersPtr; > + > /// \brief A lazy pointer to a set of CXXBaseSpecifiers. > -typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, > +typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, > &ExternalASTSource::GetExternalCXXBaseSpecifiers> > LazyCXXBaseSpecifiersPtr; > > > Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original) > +++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Tue Mar 24 > 01:36:48 2015 > @@ -86,10 +86,14 @@ public: > /// stream into an array of specifiers. > CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; > > + /// \brief Resolve a handle to a list of ctor initializers into the list of > + /// initializers themselves. > + CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) > override; > + > /// \brief Find all declarations with the given name in the > /// given context. > - bool > - FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName > Name) override; > + bool FindExternalVisibleDeclsByName(const DeclContext *DC, > + DeclarationName Name) override; > > /// \brief Ensures that the table of all visible declarations inside this > /// context is up to date. > > Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) > +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Mar 24 01:36:48 > 2015 > @@ -149,7 +149,11 @@ namespace clang { > /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an > /// AST file. > typedef uint32_t CXXBaseSpecifiersID; > - > + > + /// \brief An ID number that refers to a list of CXXCtorInitializers in > an > + /// AST file. > + typedef uint32_t CXXCtorInitializersID; > + > /// \brief An ID number that refers to an entity in the detailed > /// preprocessing record. > typedef uint32_t PreprocessedEntityID; > @@ -555,6 +559,10 @@ namespace clang { > > /// \brief Record code for potentially unused local typedef names. > UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES = 52, > + > + /// \brief Record code for the table of offsets to CXXCtorInitializers > + /// lists. > + CXX_CTOR_INITIALIZERS_OFFSETS = 53, > }; > > /// \brief Record types used within a source manager block. > @@ -1074,6 +1082,8 @@ namespace clang { > DECL_STATIC_ASSERT, > /// \brief A record containing CXXBaseSpecifiers. > DECL_CXX_BASE_SPECIFIERS, > + /// \brief A record containing CXXCtorInitializers. > + DECL_CXX_CTOR_INITIALIZERS, > /// \brief A IndirectFieldDecl record. > DECL_INDIRECTFIELD, > /// \brief A NonTypeTemplateParmDecl record that stores an expanded > > Modified: cfe/trunk/include/clang/Serialization/ASTReader.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) > +++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Mar 24 01:36:48 2015 > @@ -943,9 +943,6 @@ private: > /// passing decls to consumer. > bool PassingDeclsToConsumer; > > - /// Number of CXX base specifiers currently loaded > - unsigned NumCXXBaseSpecifiersLoaded; > - > /// \brief The set of identifiers that were read while the AST reader was > /// (recursively) loading declarations. > /// > @@ -1583,11 +1580,6 @@ public: > return Result; > } > > - /// \brief Returns the number of C++ base specifiers found in the chain. > - unsigned getTotalNumCXXBaseSpecifiers() const { > - return NumCXXBaseSpecifiersLoaded; > - } > - > /// \brief Reads a TemplateArgumentLocInfo appropriate for the > /// given TemplateArgument kind. > TemplateArgumentLocInfo > @@ -1993,10 +1985,18 @@ public: > const RecordData &Record,unsigned > &Idx); > > /// \brief Read a CXXCtorInitializer array. > - std::pair<CXXCtorInitializer **, unsigned> > + CXXCtorInitializer ** > ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, > unsigned &Idx); > > + /// \brief Read a CXXCtorInitializers ID from the given record and > + /// return its global bit offset. > + uint64_t ReadCXXCtorInitializersRef(ModuleFile &M, const RecordData > &Record, > + unsigned &Idx); > + > + /// \brief Read the contents of a CXXCtorInitializer array. > + CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) > override; > + > /// \brief Read a source location from raw form. > SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, unsigned Raw) > const { > SourceLocation Loc = SourceLocation::getFromRawEncoding(Raw); > > Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original) > +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Tue Mar 24 01:36:48 2015 > @@ -415,7 +415,7 @@ private: > unsigned NumVisibleDeclContexts; > > /// \brief The offset of each CXXBaseSpecifier set within the AST. > - SmallVector<uint32_t, 4> CXXBaseSpecifiersOffsets; > + SmallVector<uint32_t, 16> CXXBaseSpecifiersOffsets; > > /// \brief The first ID number we can use for our own base specifiers. > serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID; > @@ -443,6 +443,33 @@ private: > /// in the order they should be written. > SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite; > > + /// \brief The offset of each CXXCtorInitializer list within the AST. > + SmallVector<uint32_t, 16> CXXCtorInitializersOffsets; > + > + /// \brief The first ID number we can use for our own ctor initializers. > + serialization::CXXCtorInitializersID FirstCXXCtorInitializersID; > + > + /// \brief The ctor initializers ID that will be assigned to the next new > + /// list of C++ ctor initializers. > + serialization::CXXCtorInitializersID NextCXXCtorInitializersID; > + > + /// \brief A set of C++ ctor initializers that is queued to be written > + /// into the AST file. > + struct QueuedCXXCtorInitializers { > + QueuedCXXCtorInitializers() : ID() {} > + > + QueuedCXXCtorInitializers(serialization::CXXCtorInitializersID ID, > + ArrayRef<CXXCtorInitializer*> Inits) > + : ID(ID), Inits(Inits) {} > + > + serialization::CXXCtorInitializersID ID; > + ArrayRef<CXXCtorInitializer*> Inits; > + }; > + > + /// \brief Queue of C++ ctor initializers to be written to the AST file, > + /// in the order they should be written. > + SmallVector<QueuedCXXCtorInitializers, 2> CXXCtorInitializersToWrite; > + > /// \brief A mapping from each known submodule to its ID number, which will > /// be a positive integer. > llvm::DenseMap<Module *, unsigned> SubmoduleIDs; > @@ -471,6 +498,7 @@ private: > void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, > bool isModule); > void WriteCXXBaseSpecifiersOffsets(); > + void WriteCXXCtorInitializersOffsets(); > > unsigned TypeExtQualAbbrev; > unsigned TypeFunctionProtoAbbrev; > @@ -675,6 +703,11 @@ public: > void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, > RecordDataImpl &Record); > > + /// \brief Emit the ID for a CXXCtorInitializer array and register the > array > + /// for later serialization. > + void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits, > + RecordDataImpl &Record); > + > /// \brief Emit a CXXCtorInitializer array. > void AddCXXCtorInitializers( > const CXXCtorInitializer * const > *CtorInitializers, > @@ -747,6 +780,18 @@ public: > /// via \c AddCXXBaseSpecifiersRef(). > void FlushCXXBaseSpecifiers(); > > + /// \brief Flush all of the C++ constructor initializer lists that have > been > + /// added via \c AddCXXCtorInitializersRef(). > + void FlushCXXCtorInitializers(); > + > + /// \brief Flush all pending records that are tacked onto the end of > + /// decl and decl update records. > + void FlushPendingAfterDecl() { > + FlushStmts(); > + FlushCXXBaseSpecifiers(); > + FlushCXXCtorInitializers(); > + } > + > /// \brief Record an ID for the given switch-case statement. > unsigned RecordSwitchCaseID(SwitchCase *S); > > > Modified: cfe/trunk/include/clang/Serialization/Module.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Serialization/Module.h (original) > +++ cfe/trunk/include/clang/Serialization/Module.h Tue Mar 24 01:36:48 2015 > @@ -404,6 +404,13 @@ public: > /// indexed by the C++ base specifier set ID (-1). > const uint32_t *CXXBaseSpecifiersOffsets; > > + /// \brief The number of C++ ctor initializer lists in this AST file. > + unsigned LocalNumCXXCtorInitializers; > + > + /// \brief Offset of each C++ ctor initializer list within the bitstream, > + /// indexed by the C++ ctor initializer list ID minus 1. > + const uint32_t *CXXCtorInitializersOffsets; > + > typedef llvm::DenseMap<const DeclContext *, DeclContextInfo> > DeclContextInfosMap; > > > Modified: cfe/trunk/lib/AST/DeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclCXX.cpp (original) > +++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Mar 24 01:36:48 2015 > @@ -1739,6 +1739,10 @@ CXXConstructorDecl::Create(ASTContext &C > isImplicitlyDeclared, isConstexpr); > } > > +CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() > const { > + return CtorInitializers.get(getASTContext().getExternalSource()); > +} > + > CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const { > assert(isDelegatingConstructor() && "Not a delegating constructor!"); > Expr *E = (*init_begin())->getInit()->IgnoreImplicit(); > > Modified: cfe/trunk/lib/AST/DeclObjC.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclObjC.cpp (original) > +++ cfe/trunk/lib/AST/DeclObjC.cpp Tue Mar 24 01:36:48 2015 > @@ -1820,6 +1820,11 @@ void ObjCImplementationDecl::setIvarInit > } > } > > +ObjCImplementationDecl::init_const_iterator > +ObjCImplementationDecl::init_begin() const { > + return IvarInitializers.get(getASTContext().getExternalSource()); > +} > + > raw_ostream &clang::operator<<(raw_ostream &OS, > const ObjCImplementationDecl &ID) { > OS << ID.getName(); > > Modified: cfe/trunk/lib/AST/ExternalASTSource.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExternalASTSource.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ExternalASTSource.cpp (original) > +++ cfe/trunk/lib/AST/ExternalASTSource.cpp Tue Mar 24 01:36:48 2015 > @@ -66,6 +66,11 @@ Stmt *ExternalASTSource::GetExternalDecl > return nullptr; > } > > +CXXCtorInitializer ** > +ExternalASTSource::GetExternalCXXCtorInitializers(uint64_t Offset) { > + return nullptr; > +} > + > CXXBaseSpecifier * > ExternalASTSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) { > return nullptr; > > Modified: cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp (original) > +++ cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp Tue Mar 24 01:36:48 2015 > @@ -43,6 +43,7 @@ protected: > Selector GetExternalSelector(uint32_t ID) override; > uint32_t GetNumExternalSelectors() override; > Stmt *GetExternalDeclStmt(uint64_t Offset) override; > + CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) > override; > CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; > bool FindExternalVisibleDeclsByName(const DeclContext *DC, > DeclarationName Name) override; > @@ -232,6 +233,10 @@ CXXBaseSpecifier * > ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) { > return getFinalReader().GetExternalCXXBaseSpecifiers(Offset); > } > +CXXCtorInitializer ** > +ChainedIncludesSource::GetExternalCXXCtorInitializers(uint64_t Offset) { > + return getFinalReader().GetExternalCXXCtorInitializers(Offset); > +} > bool > ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC, > DeclarationName Name) { > > Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original) > +++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Tue Mar 24 01:36:48 > 2015 > @@ -86,6 +86,14 @@ CXXBaseSpecifier *MultiplexExternalSemaS > return nullptr; > } > > +CXXCtorInitializer ** > +MultiplexExternalSemaSource::GetExternalCXXCtorInitializers(uint64_t Offset) > { > + for (auto *S : Sources) > + if (auto *R = S->GetExternalCXXCtorInitializers(Offset)) > + return R; > + return nullptr; > +} > + > bool MultiplexExternalSemaSource:: > FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { > bool AnyDeclsFound = false; > > Modified: cfe/trunk/lib/Serialization/ASTReader.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 24 01:36:48 2015 > @@ -3204,16 +3204,26 @@ ASTReader::ReadASTBlock(ModuleFile &F, u > case OBJC_CATEGORIES: > F.ObjCCategories.swap(Record); > break; > - > + > case CXX_BASE_SPECIFIER_OFFSETS: { > if (F.LocalNumCXXBaseSpecifiers != 0) { > Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file"); > return Failure; > } > - > + > F.LocalNumCXXBaseSpecifiers = Record[0]; > F.CXXBaseSpecifiersOffsets = (const uint32_t *)Blob.data(); > - NumCXXBaseSpecifiersLoaded += F.LocalNumCXXBaseSpecifiers; > + break; > + } > + > + case CXX_CTOR_INITIALIZERS_OFFSETS: { > + if (F.LocalNumCXXCtorInitializers != 0) { > + Error("duplicate CXX_CTOR_INITIALIZERS_OFFSETS record in AST file"); > + return Failure; > + } > + > + F.LocalNumCXXCtorInitializers = Record[0]; > + F.CXXCtorInitializersOffsets = (const uint32_t *)Blob.data(); > break; > } > > @@ -6187,6 +6197,38 @@ void ASTReader::CompleteRedeclChain(cons > } > } > > +uint64_t ASTReader::ReadCXXCtorInitializersRef(ModuleFile &M, > + const RecordData &Record, > + unsigned &Idx) { > + if (Idx >= Record.size() || Record[Idx] > M.LocalNumCXXCtorInitializers) { > + Error("malformed AST file: missing C++ ctor initializers"); > + return 0; > + } > + > + unsigned LocalID = Record[Idx++]; > + return getGlobalBitOffset(M, M.CXXCtorInitializersOffsets[LocalID - 1]); > +} > + > +CXXCtorInitializer ** > +ASTReader::GetExternalCXXCtorInitializers(uint64_t Offset) { > + RecordLocation Loc = getLocalBitOffset(Offset); > + BitstreamCursor &Cursor = Loc.F->DeclsCursor; > + SavedStreamPosition SavedPosition(Cursor); > + Cursor.JumpToBit(Loc.Offset); > + ReadingKindTracker ReadingKind(Read_Decl, *this); > + > + RecordData Record; > + unsigned Code = Cursor.ReadCode(); > + unsigned RecCode = Cursor.readRecord(Code, Record); > + if (RecCode != DECL_CXX_CTOR_INITIALIZERS) { > + Error("malformed AST file: missing C++ ctor initializers"); > + return nullptr; > + } > + > + unsigned Idx = 0; > + return ReadCXXCtorInitializers(*Loc.F, Record, Idx); > +} > + > uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, > const RecordData &Record, > unsigned &Idx) { > @@ -7918,92 +7960,89 @@ ASTReader::ReadCXXBaseSpecifier(ModuleFi > return Result; > } > > -std::pair<CXXCtorInitializer **, unsigned> > +CXXCtorInitializer ** > ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, > unsigned &Idx) { > - CXXCtorInitializer **CtorInitializers = nullptr; > unsigned NumInitializers = Record[Idx++]; > - if (NumInitializers) { > - CtorInitializers > - = new (Context) CXXCtorInitializer*[NumInitializers]; > - for (unsigned i=0; i != NumInitializers; ++i) { > - TypeSourceInfo *TInfo = nullptr; > - bool IsBaseVirtual = false; > - FieldDecl *Member = nullptr; > - IndirectFieldDecl *IndirectMember = nullptr; > - > - CtorInitializerType Type = (CtorInitializerType)Record[Idx++]; > - switch (Type) { > - case CTOR_INITIALIZER_BASE: > - TInfo = GetTypeSourceInfo(F, Record, Idx); > - IsBaseVirtual = Record[Idx++]; > - break; > - > - case CTOR_INITIALIZER_DELEGATING: > - TInfo = GetTypeSourceInfo(F, Record, Idx); > - break; > + assert(NumInitializers && "wrote ctor initializers but have no inits"); > + auto **CtorInitializers = new (Context) > CXXCtorInitializer*[NumInitializers]; > + for (unsigned i = 0; i != NumInitializers; ++i) { > + TypeSourceInfo *TInfo = nullptr; > + bool IsBaseVirtual = false; > + FieldDecl *Member = nullptr; > + IndirectFieldDecl *IndirectMember = nullptr; > > - case CTOR_INITIALIZER_MEMBER: > - Member = ReadDeclAs<FieldDecl>(F, Record, Idx); > - break; > + CtorInitializerType Type = (CtorInitializerType)Record[Idx++]; > + switch (Type) { > + case CTOR_INITIALIZER_BASE: > + TInfo = GetTypeSourceInfo(F, Record, Idx); > + IsBaseVirtual = Record[Idx++]; > + break; > > - case CTOR_INITIALIZER_INDIRECT_MEMBER: > - IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx); > - break; > - } > + case CTOR_INITIALIZER_DELEGATING: > + TInfo = GetTypeSourceInfo(F, Record, Idx); > + break; > > - SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, > Idx); > - Expr *Init = ReadExpr(F); > - SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx); > - SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx); > - bool IsWritten = Record[Idx++]; > - unsigned SourceOrderOrNumArrayIndices; > - SmallVector<VarDecl *, 8> Indices; > - if (IsWritten) { > - SourceOrderOrNumArrayIndices = Record[Idx++]; > - } else { > - SourceOrderOrNumArrayIndices = Record[Idx++]; > - Indices.reserve(SourceOrderOrNumArrayIndices); > - for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i) > - Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx)); > - } > - > - CXXCtorInitializer *BOMInit; > - if (Type == CTOR_INITIALIZER_BASE) { > - BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, > IsBaseVirtual, > - LParenLoc, Init, RParenLoc, > - MemberOrEllipsisLoc); > - } else if (Type == CTOR_INITIALIZER_DELEGATING) { > - BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, LParenLoc, > - Init, RParenLoc); > - } else if (IsWritten) { > - if (Member) > - BOMInit = new (Context) CXXCtorInitializer(Context, Member, > MemberOrEllipsisLoc, > - LParenLoc, Init, RParenLoc); > - else > - BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember, > - MemberOrEllipsisLoc, > LParenLoc, > - Init, RParenLoc); > + case CTOR_INITIALIZER_MEMBER: > + Member = ReadDeclAs<FieldDecl>(F, Record, Idx); > + break; > + > + case CTOR_INITIALIZER_INDIRECT_MEMBER: > + IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx); > + break; > + } > + > + SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx); > + Expr *Init = ReadExpr(F); > + SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx); > + SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx); > + bool IsWritten = Record[Idx++]; > + unsigned SourceOrderOrNumArrayIndices; > + SmallVector<VarDecl *, 8> Indices; > + if (IsWritten) { > + SourceOrderOrNumArrayIndices = Record[Idx++]; > + } else { > + SourceOrderOrNumArrayIndices = Record[Idx++]; > + Indices.reserve(SourceOrderOrNumArrayIndices); > + for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i) > + Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx)); > + } > + > + CXXCtorInitializer *BOMInit; > + if (Type == CTOR_INITIALIZER_BASE) { > + BOMInit = new (Context) > + CXXCtorInitializer(Context, TInfo, IsBaseVirtual, LParenLoc, Init, > + RParenLoc, MemberOrEllipsisLoc); > + } else if (Type == CTOR_INITIALIZER_DELEGATING) { > + BOMInit = new (Context) > + CXXCtorInitializer(Context, TInfo, LParenLoc, Init, RParenLoc); > + } else if (IsWritten) { > + if (Member) > + BOMInit = new (Context) CXXCtorInitializer( > + Context, Member, MemberOrEllipsisLoc, LParenLoc, Init, > RParenLoc); > + else > + BOMInit = new (Context) > + CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc, > + LParenLoc, Init, RParenLoc); > + } else { > + if (IndirectMember) { > + assert(Indices.empty() && "Indirect field improperly initialized"); > + BOMInit = new (Context) > + CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc, > + LParenLoc, Init, RParenLoc); > } else { > - if (IndirectMember) { > - assert(Indices.empty() && "Indirect field improperly initialized"); > - BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember, > - MemberOrEllipsisLoc, > LParenLoc, > - Init, RParenLoc); > - } else { > - BOMInit = CXXCtorInitializer::Create(Context, Member, > MemberOrEllipsisLoc, > - LParenLoc, Init, RParenLoc, > - Indices.data(), > Indices.size()); > - } > + BOMInit = CXXCtorInitializer::Create( > + Context, Member, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc, > + Indices.data(), Indices.size()); > } > - > - if (IsWritten) > - BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices); > - CtorInitializers[i] = BOMInit; > } > + > + if (IsWritten) > + BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices); > + CtorInitializers[i] = BOMInit; > } > > - return std::make_pair(CtorInitializers, NumInitializers); > + return CtorInitializers; > } > > NestedNameSpecifier * > @@ -8680,8 +8719,7 @@ ASTReader::ASTReader(Preprocessor &PP, A > NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0), > NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0), > TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0), > - PassingDeclsToConsumer(false), NumCXXBaseSpecifiersLoaded(0), > - ReadingKind(Read_None) { > + PassingDeclsToConsumer(false), ReadingKind(Read_None) { > SourceMgr.setExternalSLocEntrySource(this); > } > > > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Mar 24 01:36:48 2015 > @@ -405,6 +405,12 @@ void ASTDeclReader::Visit(Decl *D) { > // module). > // FIXME: Can we diagnose ODR violations somehow? > if (Record[Idx++]) { > + if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) { > + CD->NumCtorInitializers = Record[Idx++]; > + if (CD->NumCtorInitializers) > + CD->CtorInitializers = > + Reader.ReadCXXCtorInitializersRef(F, Record, Idx); > + } > Reader.PendingBodies[FD] = GetCurrentCursorOffset(); > HasPendingBody = true; > } > @@ -992,8 +998,9 @@ void ASTDeclReader::VisitObjCImplementat > D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx)); > D->setHasNonZeroConstructors(Record[Idx++]); > D->setHasDestructors(Record[Idx++]); > - std::tie(D->IvarInitializers, D->NumIvarInitializers) = > - Reader.ReadCXXCtorInitializers(F, Record, Idx); > + D->NumIvarInitializers = Record[Idx++]; > + if (D->NumIvarInitializers) > + D->IvarInitializers = Reader.ReadCXXCtorInitializersRef(F, Record, Idx); > } > > > @@ -1623,9 +1630,6 @@ void ASTDeclReader::VisitCXXConstructorD > if (D->isCanonicalDecl()) > D->setInheritedConstructor(CD); > D->IsExplicitSpecified = Record[Idx++]; > - // FIXME: We should defer loading this until we need the constructor's > body. > - std::tie(D->CtorInitializers, D->NumCtorInitializers) = > - Reader.ReadCXXCtorInitializers(F, Record, Idx); > } > > void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { > @@ -3146,6 +3150,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID I > case DECL_CXX_BASE_SPECIFIERS: > Error("attempt to read a C++ base-specifier record as a declaration"); > return nullptr; > + case DECL_CXX_CTOR_INITIALIZERS: > + Error("attempt to read a C++ ctor initializer record as a declaration"); > + return nullptr; > case DECL_IMPORT: > // Note: last entry of the ImportDecl record is the number of stored > source > // locations. > @@ -3649,9 +3656,12 @@ void ASTDeclReader::UpdateDecl(Decl *D, > }); > } > FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, > Idx)); > - if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) > - std::tie(CD->CtorInitializers, CD->NumCtorInitializers) = > - Reader.ReadCXXCtorInitializers(ModuleFile, Record, Idx); > + if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) { > + CD->NumCtorInitializers = Record[Idx++]; > + if (CD->NumCtorInitializers) > + CD->CtorInitializers = > + Reader.ReadCXXCtorInitializersRef(F, Record, Idx); > + } > // Store the offset of the body so we can lazily load it later. > Reader.PendingBodies[FD] = GetCurrentCursorOffset(); > HasPendingBody = true; > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar 24 01:36:48 2015 > @@ -2694,6 +2694,29 @@ void ASTWriter::WritePragmaDiagnosticMap > Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record); > } > > +void ASTWriter::WriteCXXCtorInitializersOffsets() { > + if (CXXCtorInitializersOffsets.empty()) > + return; > + > + RecordData Record; > + > + // Create a blob abbreviation for the C++ ctor initializer offsets. > + using namespace llvm; > + > + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); > + Abbrev->Add(BitCodeAbbrevOp(CXX_CTOR_INITIALIZERS_OFFSETS)); > + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size > + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); > + unsigned CtorInitializersOffsetAbbrev = Stream.EmitAbbrev(Abbrev); > + > + // Write the base specifier offsets table. > + Record.clear(); > + Record.push_back(CXX_CTOR_INITIALIZERS_OFFSETS); > + Record.push_back(CXXCtorInitializersOffsets.size()); > + Stream.EmitRecordWithBlob(CtorInitializersOffsetAbbrev, Record, > + data(CXXCtorInitializersOffsets)); > +} > + > void ASTWriter::WriteCXXBaseSpecifiersOffsets() { > if (CXXBaseSpecifiersOffsets.empty()) > return; > @@ -4154,7 +4177,8 @@ ASTWriter::ASTWriter(llvm::BitstreamWrit > FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), > NextSelectorID(FirstSelectorID), > CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), > NumLexicalDeclContexts(0), NumVisibleDeclContexts(0), > - NextCXXBaseSpecifiersID(1), TypeExtQualAbbrev(0), > + NextCXXBaseSpecifiersID(1), NextCXXCtorInitializersID(1), > + TypeExtQualAbbrev(0), > TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0), > DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0), > UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0), > @@ -4559,6 +4583,7 @@ void ASTWriter::WriteASTCore(Sema &SemaR > if (!DeclUpdatesOffsetsRecord.empty()) > Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord); > WriteCXXBaseSpecifiersOffsets(); > + WriteCXXCtorInitializersOffsets(); > WriteFileDeclIDsMap(); > WriteSourceManagerBlock(Context.getSourceManager(), PP); > > @@ -4818,11 +4843,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(R > > Stream.EmitRecord(DECL_UPDATES, Record); > > - // Flush any statements that were written as part of this update record. > - FlushStmts(); > - > - // Flush C++ base specifiers, if there are any. > - FlushCXXBaseSpecifiers(); > + FlushPendingAfterDecl(); > } > } > > @@ -4934,8 +4955,16 @@ void ASTWriter::AddCXXTemporary(const CX > AddDeclRef(Temp->getDestructor(), Record); > } > > +void ASTWriter::AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> > Inits, > + RecordDataImpl &Record) { > + assert(!Inits.empty() && "Empty ctor initializer sets are not recorded"); > + CXXCtorInitializersToWrite.push_back( > + QueuedCXXCtorInitializers(NextCXXCtorInitializersID, Inits)); > + Record.push_back(NextCXXCtorInitializersID++); > +} > + > void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, > - CXXBaseSpecifier const *BasesEnd, > + CXXBaseSpecifier const *BasesEnd, > RecordDataImpl &Record) { > assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded"); > CXXBaseSpecifiersToWrite.push_back( > @@ -5496,7 +5525,8 @@ void ASTWriter::AddCXXBaseSpecifier(cons > > void ASTWriter::FlushCXXBaseSpecifiers() { > RecordData Record; > - for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) { > + unsigned N = CXXBaseSpecifiersToWrite.size(); > + for (unsigned I = 0; I != N; ++I) { > Record.clear(); > > // Record the offset of this base-specifier set. > @@ -5520,6 +5550,8 @@ void ASTWriter::FlushCXXBaseSpecifiers() > FlushStmts(); > } > > + assert(N == CXXBaseSpecifiersToWrite.size() && > + "added more base specifiers while writing base specifiers"); > CXXBaseSpecifiersToWrite.clear(); > } > > @@ -5561,6 +5593,35 @@ void ASTWriter::AddCXXCtorInitializers( > } > } > > +void ASTWriter::FlushCXXCtorInitializers() { > + RecordData Record; > + > + unsigned N = CXXCtorInitializersToWrite.size(); > + for (auto &Init : CXXCtorInitializersToWrite) { > + Record.clear(); > + > + // Record the offset of this mem-initializer list. > + unsigned Index = Init.ID - 1; > + if (Index == CXXCtorInitializersOffsets.size()) > + CXXCtorInitializersOffsets.push_back(Stream.GetCurrentBitNo()); > + else { > + if (Index > CXXCtorInitializersOffsets.size()) > + CXXCtorInitializersOffsets.resize(Index + 1); > + CXXCtorInitializersOffsets[Index] = Stream.GetCurrentBitNo(); > + } > + > + AddCXXCtorInitializers(Init.Inits.data(), Init.Inits.size(), Record); > + Stream.EmitRecord(serialization::DECL_CXX_CTOR_INITIALIZERS, Record); > + > + // Flush any expressions that were written as part of the initializers. > + FlushStmts(); > + } > + > + assert(N == CXXCtorInitializersToWrite.size() && > + "added more ctor initializers while writing ctor initializers"); > + CXXCtorInitializersToWrite.clear(); > +} > + > void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl > &Record) { > auto &Data = D->data(); > Record.push_back(Data.IsLambda); > > Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Mar 24 01:36:48 2015 > @@ -133,9 +133,12 @@ namespace clang { > > void AddFunctionDefinition(const FunctionDecl *FD) { > assert(FD->doesThisDeclarationHaveABody()); > - if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) > - Writer.AddCXXCtorInitializers(CD->CtorInitializers, > - CD->NumCtorInitializers, Record); > + if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) { > + Record.push_back(CD->NumCtorInitializers); > + if (CD->NumCtorInitializers) > + Writer.AddCXXCtorInitializersRef( > + llvm::makeArrayRef(CD->init_begin(), CD->init_end()), Record); > + } > Writer.AddStmt(FD->getBody()); > } > > @@ -209,7 +212,7 @@ void ASTDeclWriter::Visit(Decl *D) { > if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { > Record.push_back(FD->doesThisDeclarationHaveABody()); > if (FD->doesThisDeclarationHaveABody()) > - Writer.AddStmt(FD->getBody()); > + AddFunctionDefinition(FD); > } > } > > @@ -711,8 +714,10 @@ void ASTDeclWriter::VisitObjCImplementat > Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record); > Record.push_back(D->hasNonZeroConstructors()); > Record.push_back(D->hasDestructors()); > - Writer.AddCXXCtorInitializers(D->IvarInitializers, D->NumIvarInitializers, > - Record); > + Record.push_back(D->NumIvarInitializers); > + if (D->NumIvarInitializers) > + Writer.AddCXXCtorInitializersRef( > + llvm::makeArrayRef(D->init_begin(), D->init_end()), Record); > Code = serialization::DECL_OBJC_IMPLEMENTATION; > } > > @@ -1120,8 +1125,6 @@ void ASTDeclWriter::VisitCXXConstructorD > > Writer.AddDeclRef(D->getInheritedConstructor(), Record); > Record.push_back(D->IsExplicitSpecified); > - Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers, > - Record); > > Code = serialization::DECL_CXX_CONSTRUCTOR; > } > @@ -2066,12 +2069,10 @@ void ASTWriter::WriteDecl(ASTContext &Co > D->getDeclKindName() + "'"); > Stream.EmitRecord(W.Code, Record, W.AbbrevToUse); > > - // Flush any expressions that were written as part of this declaration. > - FlushStmts(); > - > - // Flush C++ base specifiers, if there are any. > - FlushCXXBaseSpecifiers(); > - > + // Flush any expressions, base specifiers, and ctor initializers that > + // were written as part of this declaration. > + FlushPendingAfterDecl(); > + > // Note declarations that should be deserialized eagerly so that we can add > // them to a record in the AST file later. > if (isRequiredDecl(D, Context)) > > Modified: cfe/trunk/lib/Serialization/Module.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/Module.cpp?rev=233052&r1=233051&r2=233052&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/Module.cpp (original) > +++ cfe/trunk/lib/Serialization/Module.cpp Tue Mar 24 01:36:48 2015 > @@ -38,6 +38,7 @@ ModuleFile::ModuleFile(ModuleKind Kind, > SelectorLookupTableData(nullptr), SelectorLookupTable(nullptr), > LocalNumDecls(0), DeclOffsets(nullptr), BaseDeclID(0), > LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(nullptr), > + LocalNumCXXCtorInitializers(0), CXXCtorInitializersOffsets(nullptr), > FileSortedDecls(nullptr), NumFileSortedDecls(0), > RedeclarationsMap(nullptr), LocalNumRedeclarationsInMap(0), > ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0), > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
