r265195 - [modules] Start moving the code for encoding AST records out of ASTWriter into

Adrian Prantl via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 7 17:48:58 PDT 2016


Thanks for the quick reaction! Our bots are happy again, too.

-- adrian
> On Apr 6, 2016, at 10:13 AM, Richard Smith <richard at metafoo.co.uk> wrote:
> 
> Thanks, should be fixed in r265564.
> 
> On Tue, Apr 5, 2016 at 1:44 PM, Adrian Prantl via cfe-commits <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
> Hi Richard,
> 
> it looks like this commit has caused a 6% size regression when building a PCH from OS X’s Cocoa.h. When comparing the llvm-bcanalyzer output for r265187 and r265195 the most noticeable diff is in the DECLTYPES_BLOCK:
> 
>    Block ID #11 (DECLTYPES_BLOCK):
>        Num Instances: 1
> -         Total Size: 50609331b/6326166.38B/1581541W
> -    Percent of file: 42.1507%
> +         Total Size: 55982899b/6997862.38B/1749465W
> +    Percent of file: 44.6289%
>        Num SubBlocks: 0
>          Num Abbrevs: 16
>          Num Records: 192517
> -    Percent Abbrevs: 40.5408%
> +    Percent Abbrevs: 20.3540%
> 
> And it looks like the only part of the commit that was not obviously NFC is also in ASTWriter::WriteDecl().
> 
> Could you please have a look?
> 
> Let me know if I can help provide any other diagnostics or testcases. Thanks,
> Adrian
> 
> > On Apr 1, 2016, at 3:52 PM, Richard Smith via cfe-commits <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
> >
> > Author: rsmith
> > Date: Fri Apr  1 17:52:03 2016
> > New Revision: 265195
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=265195&view=rev <http://llvm.org/viewvc/llvm-project?rev=265195&view=rev>
> > Log:
> > [modules] Start moving the code for encoding AST records out of ASTWriter into
> > a separate class. The goal is for this class to have a separate lifetime from
> > the AST writer so that it can meaningfully track pending statement nodes and
> > context for more compact encoding of various types.
> >
> > Modified:
> >    cfe/trunk/include/clang/Serialization/ASTWriter.h
> >    cfe/trunk/lib/Serialization/ASTWriter.cpp
> >    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
> >    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> >
> > Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=265195&r1=265194&r2=265195&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=265195&r1=265194&r2=265195&view=diff>
> > ==============================================================================
> > --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
> > +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Apr  1 17:52:03 2016
> > @@ -90,6 +90,7 @@ public:
> >
> >   friend class ASTDeclWriter;
> >   friend class ASTStmtWriter;
> > +  friend class ASTRecordWriter;
> > private:
> >   /// \brief Map that provides the ID numbers of each type within the
> >   /// output stream, plus those deserialized from a chained PCH.
> > @@ -523,7 +524,6 @@ private:
> >   void WriteReferencedSelectorsPool(Sema &SemaRef);
> >   void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
> >                             bool IsModule);
> > -  void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
> >   void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
> >   void WriteDeclContextVisibleUpdate(const DeclContext *DC);
> >   void WriteFPPragmaOptions(const FPOptions &Opts);
> > @@ -555,7 +555,7 @@ private:
> >
> >   void WriteDeclAbbrevs();
> >   void WriteDecl(ASTContext &Context, Decl *D);
> > -  void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
> > +  void AddFunctionDefinition(const FunctionDecl *FD, RecordDataImpl &Record);
> >
> >   uint64_t WriteASTCore(Sema &SemaRef,
> >                         StringRef isysroot, const std::string &OutputFile,
> > @@ -684,6 +684,8 @@ public:
> >   /// declaration.
> >   serialization::DeclID getDeclID(const Decl *D);
> >
> > +  void AddAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
> > +
> >   /// \brief Emit a declaration name.
> >   void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record);
> >   void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
> > @@ -864,6 +866,219 @@ public:
> >                               const RecordDecl *Record) override;
> > };
> >
> > +/// \brief An object for streaming information to a record.
> > +class ASTRecordWriter {
> > +  ASTWriter *Writer;
> > +  ASTWriter::RecordDataImpl *Record;
> > +
> > +public:
> > +  /// Construct a ASTRecordWriter that uses the default encoding scheme.
> > +  ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
> > +      : Writer(&Writer), Record(&Record) {}
> > +
> > +  /// Construct a ASTRecordWriter that uses the same encoding scheme as another
> > +  /// ASTRecordWriter.
> > +  ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record)
> > +      : Writer(Parent.Writer), Record(&Record) {}
> > +
> > +  /// \brief Extract the underlying record storage.
> > +  ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }
> > +
> > +  /// \brief Minimal vector-like interface.
> > +  /// @{
> > +  void push_back(uint64_t N) { Record->push_back(N); }
> > +  template<typename InputIterator>
> > +  void append(InputIterator begin, InputIterator end) {
> > +    Record->append(begin, end);
> > +  }
> > +  bool empty() const { return Record->empty(); }
> > +  size_t size() const { return Record->size(); }
> > +  uint64_t &operator[](size_t N) { return (*Record)[N]; }
> > +  /// @}
> > +
> > +
> > +  /// \brief Emit the record to the stream, and return its offset.
> > +  // FIXME: Allow record producers to suggest Abbrevs.
> > +  uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
> > +    uint64_t Offset = Writer->Stream.GetCurrentBitNo();
> > +    Writer->Stream.EmitRecord(Code, *Record);
> > +    return Offset;
> > +  }
> > +
> > +
> > +  /// \brief Emit a source location.
> > +  void AddSourceLocation(SourceLocation Loc) {
> > +    return Writer->AddSourceLocation(Loc, *Record);
> > +  }
> > +
> > +  /// \brief Emit a source range.
> > +  void AddSourceRange(SourceRange Range) {
> > +    return Writer->AddSourceRange(Range, *Record);
> > +  }
> > +
> > +  /// \brief Emit an integral value.
> > +  void AddAPInt(const llvm::APInt &Value) {
> > +    return Writer->AddAPInt(Value, *Record);
> > +  }
> > +
> > +  /// \brief Emit a signed integral value.
> > +  void AddAPSInt(const llvm::APSInt &Value) {
> > +    return Writer->AddAPSInt(Value, *Record);
> > +  }
> > +
> > +  /// \brief Emit a floating-point value.
> > +  void AddAPFloat(const llvm::APFloat &Value) {
> > +    return Writer->AddAPFloat(Value, *Record);
> > +  }
> > +
> > +  /// \brief Emit a reference to an identifier.
> > +  void AddIdentifierRef(const IdentifierInfo *II) {
> > +    return Writer->AddIdentifierRef(II, *Record);
> > +  }
> > +
> > +  /// \brief Emit a Selector (which is a smart pointer reference).
> > +  void AddSelectorRef(Selector S) {
> > +    return Writer->AddSelectorRef(S, *Record);
> > +  }
> > +
> > +  /// \brief Emit a CXXTemporary.
> > +  void AddCXXTemporary(const CXXTemporary *Temp) {
> > +    return Writer->AddCXXTemporary(Temp, *Record);
> > +  }
> > +
> > +  /// \brief Emit a set of C++ base specifiers.
> > +  void AddCXXBaseSpecifiersRef(const CXXBaseSpecifier *BasesBegin,
> > +                               const CXXBaseSpecifier *BasesEnd) {
> > +    return Writer->AddCXXBaseSpecifiersRef(BasesBegin, BasesEnd, *Record);
> > +  }
> > +
> > +  /// \brief Emit a reference to a type.
> > +  void AddTypeRef(QualType T) {
> > +    return Writer->AddTypeRef(T, *Record);
> > +  }
> > +
> > +  /// \brief Emits a reference to a declarator info.
> > +  void AddTypeSourceInfo(TypeSourceInfo *TInfo) {
> > +    return Writer->AddTypeSourceInfo(TInfo, *Record);
> > +  }
> > +
> > +  /// \brief Emits a template argument location info.
> > +  void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
> > +                                  const TemplateArgumentLocInfo &Arg) {
> > +    return Writer->AddTemplateArgumentLocInfo(Kind, Arg, *Record);
> > +  }
> > +
> > +  /// \brief Emits a template argument location.
> > +  void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg) {
> > +    return Writer->AddTemplateArgumentLoc(Arg, *Record);
> > +  }
> > +
> > +  /// \brief Emits an AST template argument list info.
> > +  void AddASTTemplateArgumentListInfo(
> > +      const ASTTemplateArgumentListInfo *ASTTemplArgList) {
> > +    return Writer->AddASTTemplateArgumentListInfo(ASTTemplArgList, *Record);
> > +  }
> > +
> > +  /// \brief Emit a reference to a declaration.
> > +  void AddDeclRef(const Decl *D) {
> > +    return Writer->AddDeclRef(D, *Record);
> > +  }
> > +
> > +  void AddDeclarationName(DeclarationName Name) {
> > +    return Writer->AddDeclarationName(Name, *Record);
> > +  }
> > +
> > +  void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
> > +                             DeclarationName Name) {
> > +    return Writer->AddDeclarationNameLoc(DNLoc, Name, *Record);
> > +  }
> > +
> > +  void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
> > +    return Writer->AddDeclarationNameInfo(NameInfo, *Record);
> > +  }
> > +
> > +  void AddQualifierInfo(const QualifierInfo &Info) {
> > +    return Writer->AddQualifierInfo(Info, *Record);
> > +  }
> > +
> > +  /// \brief Emit a nested name specifier.
> > +  void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
> > +    return Writer->AddNestedNameSpecifier(NNS, *Record);
> > +  }
> > +
> > +  /// \brief Emit a nested name specifier with source-location information.
> > +  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
> > +    return Writer->AddNestedNameSpecifierLoc(NNS, *Record);
> > +  }
> > +
> > +  /// \brief Emit a template name.
> > +  void AddTemplateName(TemplateName Name) {
> > +    return Writer->AddTemplateName(Name, *Record);
> > +  }
> > +
> > +  /// \brief Emit a template argument.
> > +  void AddTemplateArgument(const TemplateArgument &Arg) {
> > +    return Writer->AddTemplateArgument(Arg, *Record);
> > +  }
> > +
> > +  /// \brief Emit a template parameter list.
> > +  void AddTemplateParameterList(const TemplateParameterList *TemplateParams) {
> > +    return Writer->AddTemplateParameterList(TemplateParams, *Record);
> > +  }
> > +
> > +  /// \brief Emit a template argument list.
> > +  void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs) {
> > +    return Writer->AddTemplateArgumentList(TemplateArgs, *Record);
> > +  }
> > +
> > +  /// \brief Emit a UnresolvedSet structure.
> > +  void AddUnresolvedSet(const ASTUnresolvedSet &Set) {
> > +    return Writer->AddUnresolvedSet(Set, *Record);
> > +  }
> > +
> > +  /// \brief Emit a C++ base specifier.
> > +  void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
> > +    return Writer->AddCXXBaseSpecifier(Base, *Record);
> > +  }
> > +
> > +  /// \brief Emit the ID for a CXXCtorInitializer array and register the array
> > +  /// for later serialization.
> > +  void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits) {
> > +    return Writer->AddCXXCtorInitializersRef(Inits, *Record);
> > +  }
> > +
> > +  /// \brief Emit a CXXCtorInitializer array.
> > +  void AddCXXCtorInitializers(const CXXCtorInitializer *const *CtorInitializers,
> > +                              unsigned NumCtorInitializers) {
> > +    return Writer->AddCXXCtorInitializers(CtorInitializers, NumCtorInitializers,
> > +                                          *Record);
> > +  }
> > +
> > +  void AddCXXDefinitionData(const CXXRecordDecl *D) {
> > +    return Writer->AddCXXDefinitionData(D, *Record);
> > +  }
> > +
> > +  /// \brief Emit a string.
> > +  void AddString(StringRef Str) {
> > +    return Writer->AddString(Str, *Record);
> > +  }
> > +
> > +  /// \brief Emit a path.
> > +  void AddPath(StringRef Path) {
> > +    return Writer->AddPath(Path, *Record);
> > +  }
> > +
> > +  /// \brief Emit a version tuple.
> > +  void AddVersionTuple(const VersionTuple &Version) {
> > +    return Writer->AddVersionTuple(Version, *Record);
> > +  }
> > +
> > +  /// \brief Emit a list of attributes.
> > +  void AddAttributes(ArrayRef<const Attr*> Attrs) {
> > +    return Writer->AddAttributes(Attrs, *Record);
> > +  }
> > +};
> > +
> > /// \brief AST and semantic-analysis consumer that generates a
> > /// precompiled header from the parsed source code.
> > class PCHGenerator : public SemaConsumer {
> >
> > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=265195&r1=265194&r2=265195&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=265195&r1=265194&r2=265195&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Apr  1 17:52:03 2016
> > @@ -85,7 +85,7 @@ static StringRef bytes(const SmallVector
> > namespace {
> >   class ASTTypeWriter {
> >     ASTWriter &Writer;
> > -    ASTWriter::RecordDataImpl &Record;
> > +    ASTRecordWriter Record;
> >
> >   public:
> >     /// \brief Type code that corresponds to the record generated.
> > @@ -94,7 +94,7 @@ namespace {
> >     unsigned AbbrevToUse;
> >
> >     ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
> > -      : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { }
> > +      : Writer(Writer), Record(Writer, Record), Code(TYPE_EXT_QUAL) { }
> >
> >     void VisitArrayType(const ArrayType *T);
> >     void VisitFunctionType(const FunctionType *T);
> > @@ -111,57 +111,57 @@ void ASTTypeWriter::VisitBuiltinType(con
> > }
> >
> > void ASTTypeWriter::VisitComplexType(const ComplexType *T) {
> > -  Writer.AddTypeRef(T->getElementType(), Record);
> > +  Record.AddTypeRef(T->getElementType());
> >   Code = TYPE_COMPLEX;
> > }
> >
> > void ASTTypeWriter::VisitPointerType(const PointerType *T) {
> > -  Writer.AddTypeRef(T->getPointeeType(), Record);
> > +  Record.AddTypeRef(T->getPointeeType());
> >   Code = TYPE_POINTER;
> > }
> >
> > void ASTTypeWriter::VisitDecayedType(const DecayedType *T) {
> > -  Writer.AddTypeRef(T->getOriginalType(), Record);
> > +  Record.AddTypeRef(T->getOriginalType());
> >   Code = TYPE_DECAYED;
> > }
> >
> > void ASTTypeWriter::VisitAdjustedType(const AdjustedType *T) {
> > -  Writer.AddTypeRef(T->getOriginalType(), Record);
> > -  Writer.AddTypeRef(T->getAdjustedType(), Record);
> > +  Record.AddTypeRef(T->getOriginalType());
> > +  Record.AddTypeRef(T->getAdjustedType());
> >   Code = TYPE_ADJUSTED;
> > }
> >
> > void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
> > -  Writer.AddTypeRef(T->getPointeeType(), Record);
> > +  Record.AddTypeRef(T->getPointeeType());
> >   Code = TYPE_BLOCK_POINTER;
> > }
> >
> > void ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) {
> > -  Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record);
> > +  Record.AddTypeRef(T->getPointeeTypeAsWritten());
> >   Record.push_back(T->isSpelledAsLValue());
> >   Code = TYPE_LVALUE_REFERENCE;
> > }
> >
> > void ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) {
> > -  Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record);
> > +  Record.AddTypeRef(T->getPointeeTypeAsWritten());
> >   Code = TYPE_RVALUE_REFERENCE;
> > }
> >
> > void ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
> > -  Writer.AddTypeRef(T->getPointeeType(), Record);
> > -  Writer.AddTypeRef(QualType(T->getClass(), 0), Record);
> > +  Record.AddTypeRef(T->getPointeeType());
> > +  Record.AddTypeRef(QualType(T->getClass(), 0));
> >   Code = TYPE_MEMBER_POINTER;
> > }
> >
> > void ASTTypeWriter::VisitArrayType(const ArrayType *T) {
> > -  Writer.AddTypeRef(T->getElementType(), Record);
> > +  Record.AddTypeRef(T->getElementType());
> >   Record.push_back(T->getSizeModifier()); // FIXME: stable values
> >   Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values
> > }
> >
> > void ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {
> >   VisitArrayType(T);
> > -  Writer.AddAPInt(T->getSize(), Record);
> > +  Record.AddAPInt(T->getSize());
> >   Code = TYPE_CONSTANT_ARRAY;
> > }
> >
> > @@ -172,14 +172,14 @@ void ASTTypeWriter::VisitIncompleteArray
> >
> > void ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
> >   VisitArrayType(T);
> > -  Writer.AddSourceLocation(T->getLBracketLoc(), Record);
> > -  Writer.AddSourceLocation(T->getRBracketLoc(), Record);
> > +  Record.AddSourceLocation(T->getLBracketLoc());
> > +  Record.AddSourceLocation(T->getRBracketLoc());
> >   Writer.AddStmt(T->getSizeExpr());
> >   Code = TYPE_VARIABLE_ARRAY;
> > }
> >
> > void ASTTypeWriter::VisitVectorType(const VectorType *T) {
> > -  Writer.AddTypeRef(T->getElementType(), Record);
> > +  Record.AddTypeRef(T->getElementType());
> >   Record.push_back(T->getNumElements());
> >   Record.push_back(T->getVectorKind());
> >   Code = TYPE_VECTOR;
> > @@ -191,7 +191,7 @@ void ASTTypeWriter::VisitExtVectorType(c
> > }
> >
> > void ASTTypeWriter::VisitFunctionType(const FunctionType *T) {
> > -  Writer.AddTypeRef(T->getReturnType(), Record);
> > +  Record.AddTypeRef(T->getReturnType());
> >   FunctionType::ExtInfo C = T->getExtInfo();
> >   Record.push_back(C.getNoReturn());
> >   Record.push_back(C.getHasRegParm());
> > @@ -210,19 +210,19 @@ void ASTTypeWriter::VisitFunctionNoProto
> > }
> >
> > static void addExceptionSpec(ASTWriter &Writer, const FunctionProtoType *T,
> > -                             ASTWriter::RecordDataImpl &Record) {
> > +                             ASTRecordWriter Record) {
> >   Record.push_back(T->getExceptionSpecType());
> >   if (T->getExceptionSpecType() == EST_Dynamic) {
> >     Record.push_back(T->getNumExceptions());
> >     for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I)
> > -      Writer.AddTypeRef(T->getExceptionType(I), Record);
> > +      Record.AddTypeRef(T->getExceptionType(I));
> >   } else if (T->getExceptionSpecType() == EST_ComputedNoexcept) {
> >     Writer.AddStmt(T->getNoexceptExpr());
> >   } else if (T->getExceptionSpecType() == EST_Uninstantiated) {
> > -    Writer.AddDeclRef(T->getExceptionSpecDecl(), Record);
> > -    Writer.AddDeclRef(T->getExceptionSpecTemplate(), Record);
> > +    Record.AddDeclRef(T->getExceptionSpecDecl());
> > +    Record.AddDeclRef(T->getExceptionSpecTemplate());
> >   } else if (T->getExceptionSpecType() == EST_Unevaluated) {
> > -    Writer.AddDeclRef(T->getExceptionSpecDecl(), Record);
> > +    Record.AddDeclRef(T->getExceptionSpecDecl());
> >   }
> > }
> >
> > @@ -237,7 +237,7 @@ void ASTTypeWriter::VisitFunctionProtoTy
> >
> >   Record.push_back(T->getNumParams());
> >   for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
> > -    Writer.AddTypeRef(T->getParamType(I), Record);
> > +    Record.AddTypeRef(T->getParamType(I));
> >
> >   if (T->hasExtParameterInfos()) {
> >     for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
> > @@ -253,14 +253,14 @@ void ASTTypeWriter::VisitFunctionProtoTy
> > }
> >
> > void ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
> > -  Writer.AddDeclRef(T->getDecl(), Record);
> > +  Record.AddDeclRef(T->getDecl());
> >   Code = TYPE_UNRESOLVED_USING;
> > }
> >
> > void ASTTypeWriter::VisitTypedefType(const TypedefType *T) {
> > -  Writer.AddDeclRef(T->getDecl(), Record);
> > +  Record.AddDeclRef(T->getDecl());
> >   assert(!T->isCanonicalUnqualified() && "Invalid typedef ?");
> > -  Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record);
> > +  Record.AddTypeRef(T->getCanonicalTypeInternal());
> >   Code = TYPE_TYPEDEF;
> > }
> >
> > @@ -270,25 +270,25 @@ void ASTTypeWriter::VisitTypeOfExprType(
> > }
> >
> > void ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) {
> > -  Writer.AddTypeRef(T->getUnderlyingType(), Record);
> > +  Record.AddTypeRef(T->getUnderlyingType());
> >   Code = TYPE_TYPEOF;
> > }
> >
> > void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) {
> > -  Writer.AddTypeRef(T->getUnderlyingType(), Record);
> > +  Record.AddTypeRef(T->getUnderlyingType());
> >   Writer.AddStmt(T->getUnderlyingExpr());
> >   Code = TYPE_DECLTYPE;
> > }
> >
> > void ASTTypeWriter::VisitUnaryTransformType(const UnaryTransformType *T) {
> > -  Writer.AddTypeRef(T->getBaseType(), Record);
> > -  Writer.AddTypeRef(T->getUnderlyingType(), Record);
> > +  Record.AddTypeRef(T->getBaseType());
> > +  Record.AddTypeRef(T->getUnderlyingType());
> >   Record.push_back(T->getUTTKind());
> >   Code = TYPE_UNARY_TRANSFORM;
> > }
> >
> > void ASTTypeWriter::VisitAutoType(const AutoType *T) {
> > -  Writer.AddTypeRef(T->getDeducedType(), Record);
> > +  Record.AddTypeRef(T->getDeducedType());
> >   Record.push_back((unsigned)T->getKeyword());
> >   if (T->getDeducedType().isNull())
> >     Record.push_back(T->isDependentType());
> > @@ -297,7 +297,7 @@ void ASTTypeWriter::VisitAutoType(const
> >
> > void ASTTypeWriter::VisitTagType(const TagType *T) {
> >   Record.push_back(T->isDependentType());
> > -  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
> > +  Record.AddDeclRef(T->getDecl()->getCanonicalDecl());
> >   assert(!T->isBeingDefined() &&
> >          "Cannot serialize in the middle of a type definition");
> > }
> > @@ -313,8 +313,8 @@ void ASTTypeWriter::VisitEnumType(const
> > }
> >
> > void ASTTypeWriter::VisitAttributedType(const AttributedType *T) {
> > -  Writer.AddTypeRef(T->getModifiedType(), Record);
> > -  Writer.AddTypeRef(T->getEquivalentType(), Record);
> > +  Record.AddTypeRef(T->getModifiedType());
> > +  Record.AddTypeRef(T->getEquivalentType());
> >   Record.push_back(T->getAttrKind());
> >   Code = TYPE_ATTRIBUTED;
> > }
> > @@ -322,16 +322,16 @@ void ASTTypeWriter::VisitAttributedType(
> > void
> > ASTTypeWriter::VisitSubstTemplateTypeParmType(
> >                                         const SubstTemplateTypeParmType *T) {
> > -  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
> > -  Writer.AddTypeRef(T->getReplacementType(), Record);
> > +  Record.AddTypeRef(QualType(T->getReplacedParameter(), 0));
> > +  Record.AddTypeRef(T->getReplacementType());
> >   Code = TYPE_SUBST_TEMPLATE_TYPE_PARM;
> > }
> >
> > void
> > ASTTypeWriter::VisitSubstTemplateTypeParmPackType(
> >                                       const SubstTemplateTypeParmPackType *T) {
> > -  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
> > -  Writer.AddTemplateArgument(T->getArgumentPack(), Record);
> > +  Record.AddTypeRef(QualType(T->getReplacedParameter(), 0));
> > +  Record.AddTemplateArgument(T->getArgumentPack());
> >   Code = TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK;
> > }
> >
> > @@ -339,14 +339,14 @@ void
> > ASTTypeWriter::VisitTemplateSpecializationType(
> >                                        const TemplateSpecializationType *T) {
> >   Record.push_back(T->isDependentType());
> > -  Writer.AddTemplateName(T->getTemplateName(), Record);
> > +  Record.AddTemplateName(T->getTemplateName());
> >   Record.push_back(T->getNumArgs());
> >   for (const auto &ArgI : *T)
> > -    Writer.AddTemplateArgument(ArgI, Record);
> > -  Writer.AddTypeRef(T->isTypeAlias() ? T->getAliasedType() :
> > -                    T->isCanonicalUnqualified() ? QualType()
> > -                                                : T->getCanonicalTypeInternal(),
> > -                    Record);
> > +    Record.AddTemplateArgument(ArgI);
> > +  Record.AddTypeRef(T->isTypeAlias() ? T->getAliasedType()
> > +                                     : T->isCanonicalUnqualified()
> > +                                           ? QualType()
> > +                                           : T->getCanonicalTypeInternal());
> >   Code = TYPE_TEMPLATE_SPECIALIZATION;
> > }
> >
> > @@ -354,7 +354,7 @@ void
> > ASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
> >   VisitArrayType(T);
> >   Writer.AddStmt(T->getSizeExpr());
> > -  Writer.AddSourceRange(T->getBracketsRange(), Record);
> > +  Record.AddSourceRange(T->getBracketsRange());
> >   Code = TYPE_DEPENDENT_SIZED_ARRAY;
> > }
> >
> > @@ -370,18 +370,17 @@ ASTTypeWriter::VisitTemplateTypeParmType
> >   Record.push_back(T->getDepth());
> >   Record.push_back(T->getIndex());
> >   Record.push_back(T->isParameterPack());
> > -  Writer.AddDeclRef(T->getDecl(), Record);
> > +  Record.AddDeclRef(T->getDecl());
> >   Code = TYPE_TEMPLATE_TYPE_PARM;
> > }
> >
> > void
> > ASTTypeWriter::VisitDependentNameType(const DependentNameType *T) {
> >   Record.push_back(T->getKeyword());
> > -  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
> > -  Writer.AddIdentifierRef(T->getIdentifier(), Record);
> > -  Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType()
> > -                                                : T->getCanonicalTypeInternal(),
> > -                    Record);
> > +  Record.AddNestedNameSpecifier(T->getQualifier());
> > +  Record.AddIdentifierRef(T->getIdentifier());
> > +  Record.AddTypeRef(
> > +      T->isCanonicalUnqualified() ? QualType() : T->getCanonicalTypeInternal());
> >   Code = TYPE_DEPENDENT_NAME;
> > }
> >
> > @@ -389,16 +388,16 @@ void
> > ASTTypeWriter::VisitDependentTemplateSpecializationType(
> >                                 const DependentTemplateSpecializationType *T) {
> >   Record.push_back(T->getKeyword());
> > -  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
> > -  Writer.AddIdentifierRef(T->getIdentifier(), Record);
> > +  Record.AddNestedNameSpecifier(T->getQualifier());
> > +  Record.AddIdentifierRef(T->getIdentifier());
> >   Record.push_back(T->getNumArgs());
> >   for (const auto &I : *T)
> > -    Writer.AddTemplateArgument(I, Record);
> > +    Record.AddTemplateArgument(I);
> >   Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION;
> > }
> >
> > void ASTTypeWriter::VisitPackExpansionType(const PackExpansionType *T) {
> > -  Writer.AddTypeRef(T->getPattern(), Record);
> > +  Record.AddTypeRef(T->getPattern());
> >   if (Optional<unsigned> NumExpansions = T->getNumExpansions())
> >     Record.push_back(*NumExpansions + 1);
> >   else
> > @@ -407,55 +406,55 @@ void ASTTypeWriter::VisitPackExpansionTy
> > }
> >
> > void ASTTypeWriter::VisitParenType(const ParenType *T) {
> > -  Writer.AddTypeRef(T->getInnerType(), Record);
> > +  Record.AddTypeRef(T->getInnerType());
> >   Code = TYPE_PAREN;
> > }
> >
> > void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
> >   Record.push_back(T->getKeyword());
> > -  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
> > -  Writer.AddTypeRef(T->getNamedType(), Record);
> > +  Record.AddNestedNameSpecifier(T->getQualifier());
> > +  Record.AddTypeRef(T->getNamedType());
> >   Code = TYPE_ELABORATED;
> > }
> >
> > void ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
> > -  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
> > -  Writer.AddTypeRef(T->getInjectedSpecializationType(), Record);
> > +  Record.AddDeclRef(T->getDecl()->getCanonicalDecl());
> > +  Record.AddTypeRef(T->getInjectedSpecializationType());
> >   Code = TYPE_INJECTED_CLASS_NAME;
> > }
> >
> > void ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
> > -  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
> > +  Record.AddDeclRef(T->getDecl()->getCanonicalDecl());
> >   Code = TYPE_OBJC_INTERFACE;
> > }
> >
> > void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
> > -  Writer.AddTypeRef(T->getBaseType(), Record);
> > +  Record.AddTypeRef(T->getBaseType());
> >   Record.push_back(T->getTypeArgsAsWritten().size());
> >   for (auto TypeArg : T->getTypeArgsAsWritten())
> > -    Writer.AddTypeRef(TypeArg, Record);
> > +    Record.AddTypeRef(TypeArg);
> >   Record.push_back(T->getNumProtocols());
> >   for (const auto *I : T->quals())
> > -    Writer.AddDeclRef(I, Record);
> > +    Record.AddDeclRef(I);
> >   Record.push_back(T->isKindOfTypeAsWritten());
> >   Code = TYPE_OBJC_OBJECT;
> > }
> >
> > void
> > ASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
> > -  Writer.AddTypeRef(T->getPointeeType(), Record);
> > +  Record.AddTypeRef(T->getPointeeType());
> >   Code = TYPE_OBJC_OBJECT_POINTER;
> > }
> >
> > void
> > ASTTypeWriter::VisitAtomicType(const AtomicType *T) {
> > -  Writer.AddTypeRef(T->getValueType(), Record);
> > +  Record.AddTypeRef(T->getValueType());
> >   Code = TYPE_ATOMIC;
> > }
> >
> > void
> > ASTTypeWriter::VisitPipeType(const PipeType *T) {
> > -  Writer.AddTypeRef(T->getElementType(), Record);
> > +  Record.AddTypeRef(T->getElementType());
> >   Code = TYPE_PIPE;
> > }
> >
> > @@ -463,11 +462,11 @@ namespace {
> >
> > class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
> >   ASTWriter &Writer;
> > -  ASTWriter::RecordDataImpl &Record;
> > +  ASTRecordWriter Record;
> >
> > public:
> >   TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
> > -    : Writer(Writer), Record(Record) { }
> > +    : Writer(Writer), Record(Writer, Record) { }
> >
> > #define ABSTRACT_TYPELOC(CLASS, PARENT)
> > #define TYPELOC(CLASS, PARENT) \
> > @@ -484,7 +483,7 @@ void TypeLocWriter::VisitQualifiedTypeLo
> >   // nothing to do
> > }
> > void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getBuiltinLoc(), Record);
> > +  Record.AddSourceLocation(TL.getBuiltinLoc());
> >   if (TL.needsExtraLocalData()) {
> >     Record.push_back(TL.getWrittenTypeSpec());
> >     Record.push_back(TL.getWrittenSignSpec());
> > @@ -493,10 +492,10 @@ void TypeLocWriter::VisitBuiltinTypeLoc(
> >   }
> > }
> > void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getStarLoc(), Record);
> > +  Record.AddSourceLocation(TL.getStarLoc());
> > }
> > void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
> >   // nothing to do
> > @@ -505,21 +504,21 @@ void TypeLocWriter::VisitAdjustedTypeLoc
> >   // nothing to do
> > }
> > void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getCaretLoc(), Record);
> > +  Record.AddSourceLocation(TL.getCaretLoc());
> > }
> > void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getAmpLoc(), Record);
> > +  Record.AddSourceLocation(TL.getAmpLoc());
> > }
> > void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record);
> > +  Record.AddSourceLocation(TL.getAmpAmpLoc());
> > }
> > void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getStarLoc(), Record);
> > -  Writer.AddTypeSourceInfo(TL.getClassTInfo(), Record);
> > +  Record.AddSourceLocation(TL.getStarLoc());
> > +  Record.AddTypeSourceInfo(TL.getClassTInfo());
> > }
> > void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getLBracketLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRBracketLoc(), Record);
> > +  Record.AddSourceLocation(TL.getLBracketLoc());
> > +  Record.AddSourceLocation(TL.getRBracketLoc());
> >   Record.push_back(TL.getSizeExpr() ? 1 : 0);
> >   if (TL.getSizeExpr())
> >     Writer.AddStmt(TL.getSizeExpr());
> > @@ -539,21 +538,21 @@ void TypeLocWriter::VisitDependentSizedA
> > }
> > void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
> >                                         DependentSizedExtVectorTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getLocalRangeBegin(), Record);
> > -  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getLocalRangeEnd(), Record);
> > +  Record.AddSourceLocation(TL.getLocalRangeBegin());
> > +  Record.AddSourceLocation(TL.getLParenLoc());
> > +  Record.AddSourceLocation(TL.getRParenLoc());
> > +  Record.AddSourceLocation(TL.getLocalRangeEnd());
> >   for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
> > -    Writer.AddDeclRef(TL.getParam(i), Record);
> > +    Record.AddDeclRef(TL.getParam(i));
> > }
> > void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
> >   VisitFunctionTypeLoc(TL);
> > @@ -562,131 +561,131 @@ void TypeLocWriter::VisitFunctionNoProto
> >   VisitFunctionTypeLoc(TL);
> > }
> > void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
> > +  Record.AddSourceLocation(TL.getTypeofLoc());
> > +  Record.AddSourceLocation(TL.getLParenLoc());
> > +  Record.AddSourceLocation(TL.getRParenLoc());
> > }
> > void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
> > -  Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record);
> > +  Record.AddSourceLocation(TL.getTypeofLoc());
> > +  Record.AddSourceLocation(TL.getLParenLoc());
> > +  Record.AddSourceLocation(TL.getRParenLoc());
> > +  Record.AddTypeSourceInfo(TL.getUnderlyingTInfo());
> > }
> > void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getKWLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
> > -  Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record);
> > +  Record.AddSourceLocation(TL.getKWLoc());
> > +  Record.AddSourceLocation(TL.getLParenLoc());
> > +  Record.AddSourceLocation(TL.getRParenLoc());
> > +  Record.AddTypeSourceInfo(TL.getUnderlyingTInfo());
> > }
> > void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getAttrNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getAttrNameLoc());
> >   if (TL.hasAttrOperand()) {
> >     SourceRange range = TL.getAttrOperandParensRange();
> > -    Writer.AddSourceLocation(range.getBegin(), Record);
> > -    Writer.AddSourceLocation(range.getEnd(), Record);
> > +    Record.AddSourceLocation(range.getBegin());
> > +    Record.AddSourceLocation(range.getEnd());
> >   }
> >   if (TL.hasAttrExprOperand()) {
> >     Expr *operand = TL.getAttrExprOperand();
> >     Record.push_back(operand ? 1 : 0);
> >     if (operand) Writer.AddStmt(operand);
> >   } else if (TL.hasAttrEnumOperand()) {
> > -    Writer.AddSourceLocation(TL.getAttrEnumOperandLoc(), Record);
> > +    Record.AddSourceLocation(TL.getAttrEnumOperandLoc());
> >   }
> > }
> > void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
> >                                             SubstTemplateTypeParmTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
> >                                           SubstTemplateTypeParmPackTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
> >                                            TemplateSpecializationTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getTemplateKeywordLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
> > +  Record.AddSourceLocation(TL.getTemplateKeywordLoc());
> > +  Record.AddSourceLocation(TL.getTemplateNameLoc());
> > +  Record.AddSourceLocation(TL.getLAngleLoc());
> > +  Record.AddSourceLocation(TL.getRAngleLoc());
> >   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
> > -    Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(),
> > -                                      TL.getArgLoc(i).getLocInfo(), Record);
> > +    Record.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(),
> > +                                      TL.getArgLoc(i).getLocInfo());
> > }
> > void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
> > +  Record.AddSourceLocation(TL.getLParenLoc());
> > +  Record.AddSourceLocation(TL.getRParenLoc());
> > }
> > void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getElaboratedKeywordLoc(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
> > +  Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
> > +  Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
> > }
> > void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getElaboratedKeywordLoc(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
> > +  Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
> >        DependentTemplateSpecializationTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getElaboratedKeywordLoc(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getTemplateKeywordLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
> > +  Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
> > +  Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
> > +  Record.AddSourceLocation(TL.getTemplateKeywordLoc());
> > +  Record.AddSourceLocation(TL.getTemplateNameLoc());
> > +  Record.AddSourceLocation(TL.getLAngleLoc());
> > +  Record.AddSourceLocation(TL.getRAngleLoc());
> >   for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
> > -    Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(),
> > -                                      TL.getArgLoc(I).getLocInfo(), Record);
> > +    Record.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(),
> > +                                      TL.getArgLoc(I).getLocInfo());
> > }
> > void TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getEllipsisLoc(), Record);
> > +  Record.AddSourceLocation(TL.getEllipsisLoc());
> > }
> > void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getNameLoc(), Record);
> > +  Record.AddSourceLocation(TL.getNameLoc());
> > }
> > void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
> >   Record.push_back(TL.hasBaseTypeAsWritten());
> > -  Writer.AddSourceLocation(TL.getTypeArgsLAngleLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getTypeArgsRAngleLoc(), Record);
> > +  Record.AddSourceLocation(TL.getTypeArgsLAngleLoc());
> > +  Record.AddSourceLocation(TL.getTypeArgsRAngleLoc());
> >   for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)
> > -    Writer.AddTypeSourceInfo(TL.getTypeArgTInfo(i), Record);
> > -  Writer.AddSourceLocation(TL.getProtocolLAngleLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getProtocolRAngleLoc(), Record);
> > +    Record.AddTypeSourceInfo(TL.getTypeArgTInfo(i));
> > +  Record.AddSourceLocation(TL.getProtocolLAngleLoc());
> > +  Record.AddSourceLocation(TL.getProtocolRAngleLoc());
> >   for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
> > -    Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
> > +    Record.AddSourceLocation(TL.getProtocolLoc(i));
> > }
> > void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getStarLoc(), Record);
> > +  Record.AddSourceLocation(TL.getStarLoc());
> > }
> > void TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getKWLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
> > -  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
> > +  Record.AddSourceLocation(TL.getKWLoc());
> > +  Record.AddSourceLocation(TL.getLParenLoc());
> > +  Record.AddSourceLocation(TL.getRParenLoc());
> > }
> > void TypeLocWriter::VisitPipeTypeLoc(PipeTypeLoc TL) {
> > -  Writer.AddSourceLocation(TL.getKWLoc(), Record);
> > +  Record.AddSourceLocation(TL.getKWLoc());
> > }
> >
> > void ASTWriter::WriteTypeAbbrevs() {
> > @@ -3989,9 +3988,9 @@ void ASTWriter::WriteModuleFileExtension
> > // General Serialization Routines
> > //===----------------------------------------------------------------------===//
> >
> > -/// \brief Write a record containing the given attributes.
> > -void ASTWriter::WriteAttributes(ArrayRef<const Attr*> Attrs,
> > -                                RecordDataImpl &Record) {
> > +/// \brief Emit the list of attributes to the specified record.
> > +void ASTWriter::AddAttributes(ArrayRef<const Attr *> Attrs,
> > +                              RecordDataImpl &Record) {
> >   Record.push_back(Attrs.size());
> >   for (const auto *A : Attrs) {
> >     Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs
> > @@ -4656,11 +4655,18 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >     const Decl *D = DeclUpdate.first;
> >
> >     bool HasUpdatedBody = false;
> > -    RecordData Record;
> > +    RecordData RecordData;
> > +    ASTRecordWriter Record(*this, RecordData);
> >     for (auto &Update : DeclUpdate.second) {
> >       DeclUpdateKind Kind = (DeclUpdateKind)Update.getKind();
> >
> > -      Record.push_back(Kind);
> > +      // An updated body is emitted last, so that the reader doesn't need
> > +      // to skip over the lazy body to reach statements for other records.
> > +      if (Kind == UPD_CXX_ADDED_FUNCTION_DEFINITION)
> > +        HasUpdatedBody = true;
> > +      else
> > +        Record.push_back(Kind);
> > +
> >       switch (Kind) {
> >       case UPD_CXX_ADDED_IMPLICIT_MEMBER:
> >       case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
> > @@ -4670,14 +4676,10 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >         break;
> >
> >       case UPD_CXX_ADDED_FUNCTION_DEFINITION:
> > -        // An updated body is emitted last, so that the reader doesn't need
> > -        // to skip over the lazy body to reach statements for other records.
> > -        Record.pop_back();
> > -        HasUpdatedBody = true;
> >         break;
> >
> >       case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
> > -        AddSourceLocation(Update.getLoc(), Record);
> > +        Record.AddSourceLocation(Update.getLoc());
> >         break;
> >
> >       case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT:
> > @@ -4688,7 +4690,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >       case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
> >         auto *RD = cast<CXXRecordDecl>(D);
> >         UpdatedDeclContexts.insert(RD->getPrimaryContext());
> > -        AddCXXDefinitionData(RD, Record);
> > +        Record.AddCXXDefinitionData(RD);
> >         Record.push_back(WriteDeclContextLexicalBlock(
> >             *Context, const_cast<CXXRecordDecl *>(RD)));
> >
> > @@ -4697,11 +4699,11 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >         // to it referring to the template definition.
> >         if (auto *MSInfo = RD->getMemberSpecializationInfo()) {
> >           Record.push_back(MSInfo->getTemplateSpecializationKind());
> > -          AddSourceLocation(MSInfo->getPointOfInstantiation(), Record);
> > +          Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
> >         } else {
> >           auto *Spec = cast<ClassTemplateSpecializationDecl>(RD);
> >           Record.push_back(Spec->getTemplateSpecializationKind());
> > -          AddSourceLocation(Spec->getPointOfInstantiation(), Record);
> > +          Record.AddSourceLocation(Spec->getPointOfInstantiation());
> >
> >           // The instantiation might have been resolved to a partial
> >           // specialization. If so, record which one.
> > @@ -4709,30 +4711,29 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >           if (auto PartialSpec =
> >                 From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) {
> >             Record.push_back(true);
> > -            AddDeclRef(PartialSpec, Record);
> > -            AddTemplateArgumentList(&Spec->getTemplateInstantiationArgs(),
> > -                                    Record);
> > +            Record.AddDeclRef(PartialSpec);
> > +            Record.AddTemplateArgumentList(
> > +                &Spec->getTemplateInstantiationArgs());
> >           } else {
> >             Record.push_back(false);
> >           }
> >         }
> >         Record.push_back(RD->getTagKind());
> > -        AddSourceLocation(RD->getLocation(), Record);
> > -        AddSourceLocation(RD->getLocStart(), Record);
> > -        AddSourceLocation(RD->getRBraceLoc(), Record);
> > +        Record.AddSourceLocation(RD->getLocation());
> > +        Record.AddSourceLocation(RD->getLocStart());
> > +        Record.AddSourceLocation(RD->getRBraceLoc());
> >
> >         // Instantiation may change attributes; write them all out afresh.
> >         Record.push_back(D->hasAttrs());
> > -        if (Record.back())
> > -          WriteAttributes(llvm::makeArrayRef(D->getAttrs().begin(),
> > -                                             D->getAttrs().size()), Record);
> > +        if (D->hasAttrs())
> > +          Record.AddAttributes(D->getAttrs());
> >
> >         // FIXME: Ensure we don't get here for explicit instantiations.
> >         break;
> >       }
> >
> >       case UPD_CXX_RESOLVED_DTOR_DELETE:
> > -        AddDeclRef(Update.getDecl(), Record);
> > +        Record.AddDeclRef(Update.getDecl());
> >         break;
> >
> >       case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
> > @@ -4755,8 +4756,8 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >         break;
> >
> >       case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:
> > -        AddSourceRange(D->getAttr<OMPThreadPrivateDeclAttr>()->getRange(),
> > -                       Record);
> > +        Record.AddSourceRange(
> > +            D->getAttr<OMPThreadPrivateDeclAttr>()->getRange());
> >         break;
> >
> >       case UPD_DECL_EXPORTED:
> > @@ -4764,7 +4765,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >         break;
> >
> >       case UPD_ADDED_ATTR_TO_RECORD:
> > -        WriteAttributes(llvm::makeArrayRef(Update.getAttr()), Record);
> > +        Record.AddAttributes(llvm::makeArrayRef(Update.getAttr()));
> >         break;
> >       }
> >     }
> > @@ -4773,14 +4774,12 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
> >       const auto *Def = cast<FunctionDecl>(D);
> >       Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);
> >       Record.push_back(Def->isInlined());
> > -      AddSourceLocation(Def->getInnerLocStart(), Record);
> > -      AddFunctionDefinition(Def, Record);
> > +      Record.AddSourceLocation(Def->getInnerLocStart());
> > +      AddFunctionDefinition(Def, Record.getRecordData());
> >     }
> >
> >     OffsetsRecord.push_back(GetDeclRef(D));
> > -    OffsetsRecord.push_back(Stream.GetCurrentBitNo());
> > -
> > -    Stream.EmitRecord(DECL_UPDATES, Record);
> > +    OffsetsRecord.push_back(Record.Emit(DECL_UPDATES));
> >
> >     FlushPendingAfterDecl();
> >   }
> >
> > Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=265195&r1=265194&r2=265195&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=265195&r1=265194&r2=265195&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Apr  1 17:52:03 2016
> > @@ -32,18 +32,31 @@ using namespace serialization;
> >
> > namespace clang {
> >   class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
> > -
> >     ASTWriter &Writer;
> >     ASTContext &Context;
> > -    typedef ASTWriter::RecordData RecordData;
> > -    RecordData &Record;
> > +    ASTRecordWriter Record;
> >
> > -  public:
> >     serialization::DeclCode Code;
> >     unsigned AbbrevToUse;
> >
> > -    ASTDeclWriter(ASTWriter &Writer, ASTContext &Context, RecordData &Record)
> > -      : Writer(Writer), Context(Context), Record(Record) {
> > +  public:
> > +    ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
> > +                  ASTWriter::RecordDataImpl &Record)
> > +        : Writer(Writer), Context(Context), Record(Writer, Record),
> > +          Code((serialization::DeclCode)0), AbbrevToUse(0) {}
> > +
> > +    uint64_t Emit(Decl *D) {
> > +      if (!Code)
> > +        llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
> > +            D->getDeclKindName() + "'");
> > +
> > +      auto Offset = Record.Emit(Code, AbbrevToUse);
> > +
> > +      // Flush any expressions, base specifiers, and ctor initializers that
> > +      // were written as part of this declaration.
> > +      Writer.FlushPendingAfterDecl();
> > +
> > +      return Offset;
> >     }
> >
> >     void Visit(Decl *D);
> > @@ -152,10 +165,10 @@ namespace clang {
> >
> >       Record.push_back(typeParams->size());
> >       for (auto typeParam : *typeParams) {
> > -        Writer.AddDeclRef(typeParam, Record);
> > +        Record.AddDeclRef(typeParam);
> >       }
> > -      Writer.AddSourceLocation(typeParams->getLAngleLoc(), Record);
> > -      Writer.AddSourceLocation(typeParams->getRAngleLoc(), Record);
> > +      Record.AddSourceLocation(typeParams->getLAngleLoc());
> > +      Record.AddSourceLocation(typeParams->getRAngleLoc());
> >     }
> >
> >     void AddFunctionDefinition(const FunctionDecl *FD) {
> > @@ -163,8 +176,8 @@ namespace clang {
> >       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);
> > +          Record.AddCXXCtorInitializersRef(
> > +              llvm::makeArrayRef(CD->init_begin(), CD->init_end()));
> >       }
> >       Writer.AddStmt(FD->getBody());
> >     }
> > @@ -182,7 +195,7 @@ namespace clang {
> >           Firsts[nullptr] = R;
> >       }
> >       for (const auto &F : Firsts)
> > -        Writer.AddDeclRef(F.second, Record);
> > +        Record.AddDeclRef(F.second);
> >     }
> >
> >     /// Get the specialization decl from an entry in the specialization list.
> > @@ -271,7 +284,7 @@ void ASTDeclWriter::Visit(Decl *D) {
> >   // abbreviation infrastructure requires that arrays are encoded last, so
> >   // we handle it here in the case of those classes derived from DeclaratorDecl
> >   if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
> > -    Writer.AddTypeSourceInfo(DD->getTypeSourceInfo(), Record);
> > +    Record.AddTypeSourceInfo(DD->getTypeSourceInfo());
> >   }
> >
> >   // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
> > @@ -285,16 +298,15 @@ void ASTDeclWriter::Visit(Decl *D) {
> > }
> >
> > void ASTDeclWriter::VisitDecl(Decl *D) {
> > -  Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
> > +  Record.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()));
> >   if (D->getDeclContext() != D->getLexicalDeclContext())
> > -    Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
> > +    Record.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()));
> >   else
> >     Record.push_back(0);
> >   Record.push_back(D->isInvalidDecl());
> >   Record.push_back(D->hasAttrs());
> >   if (D->hasAttrs())
> > -    Writer.WriteAttributes(llvm::makeArrayRef(D->getAttrs().begin(),
> > -                                              D->getAttrs().size()), Record);
> > +    Record.AddAttributes(D->getAttrs());
> >   Record.push_back(D->isImplicit());
> >   Record.push_back(D->isUsed(false));
> >   Record.push_back(D->isReferenced());
> > @@ -328,9 +340,9 @@ void ASTDeclWriter::VisitPragmaCommentDe
> >   StringRef Arg = D->getArg();
> >   Record.push_back(Arg.size());
> >   VisitDecl(D);
> > -  Writer.AddSourceLocation(D->getLocStart(), Record);
> > +  Record.AddSourceLocation(D->getLocStart());
> >   Record.push_back(D->getCommentKind());
> > -  Writer.AddString(Arg, Record);
> > +  Record.AddString(Arg);
> >   Code = serialization::DECL_PRAGMA_COMMENT;
> > }
> >
> > @@ -340,9 +352,9 @@ void ASTDeclWriter::VisitPragmaDetectMis
> >   StringRef Value = D->getValue();
> >   Record.push_back(Name.size() + 1 + Value.size());
> >   VisitDecl(D);
> > -  Writer.AddSourceLocation(D->getLocStart(), Record);
> > -  Writer.AddString(Name, Record);
> > -  Writer.AddString(Value, Record);
> > +  Record.AddSourceLocation(D->getLocStart());
> > +  Record.AddString(Name);
> > +  Record.AddString(Value);
> >   Code = serialization::DECL_PRAGMA_DETECT_MISMATCH;
> > }
> >
> > @@ -352,7 +364,7 @@ void ASTDeclWriter::VisitTranslationUnit
> >
> > void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
> >   VisitDecl(D);
> > -  Writer.AddDeclarationName(D->getDeclName(), Record);
> > +  Record.AddDeclarationName(D->getDeclName());
> >   Record.push_back(needsAnonymousDeclarationNumber(D)
> >                        ? Writer.getAnonymousDeclarationNumber(D)
> >                        : 0);
> > @@ -360,17 +372,17 @@ void ASTDeclWriter::VisitNamedDecl(Named
> >
> > void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddSourceLocation(D->getLocStart(), Record);
> > -  Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
> > +  Record.AddSourceLocation(D->getLocStart());
> > +  Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
> > }
> >
> > void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
> >   VisitRedeclarable(D);
> >   VisitTypeDecl(D);
> > -  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
> > +  Record.AddTypeSourceInfo(D->getTypeSourceInfo());
> >   Record.push_back(D->isModed());
> >   if (D->isModed())
> > -    Writer.AddTypeRef(D->getUnderlyingType(), Record);
> > +    Record.AddTypeRef(D->getUnderlyingType());
> > }
> >
> > void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
> > @@ -391,7 +403,7 @@ void ASTDeclWriter::VisitTypedefDecl(Typ
> >
> > void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
> >   VisitTypedefNameDecl(D);
> > -  Writer.AddDeclRef(D->getDescribedAliasTemplate(), Record);
> > +  Record.AddDeclRef(D->getDescribedAliasTemplate());
> >   Code = serialization::DECL_TYPEALIAS;
> > }
> >
> > @@ -405,15 +417,15 @@ void ASTDeclWriter::VisitTagDecl(TagDecl
> >   Record.push_back(D->isEmbeddedInDeclarator());
> >   Record.push_back(D->isFreeStanding());
> >   Record.push_back(D->isCompleteDefinitionRequired());
> > -  Writer.AddSourceLocation(D->getRBraceLoc(), Record);
> > +  Record.AddSourceLocation(D->getRBraceLoc());
> >
> >   if (D->hasExtInfo()) {
> >     Record.push_back(1);
> > -    Writer.AddQualifierInfo(*D->getExtInfo(), Record);
> > +    Record.AddQualifierInfo(*D->getExtInfo());
> >   } else if (auto *TD = D->getTypedefNameForAnonDecl()) {
> >     Record.push_back(2);
> > -    Writer.AddDeclRef(TD, Record);
> > -    Writer.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo(), Record);
> > +    Record.AddDeclRef(TD);
> > +    Record.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo());
> >   } else {
> >     Record.push_back(0);
> >   }
> > @@ -421,21 +433,21 @@ void ASTDeclWriter::VisitTagDecl(TagDecl
> >
> > void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
> >   VisitTagDecl(D);
> > -  Writer.AddTypeSourceInfo(D->getIntegerTypeSourceInfo(), Record);
> > +  Record.AddTypeSourceInfo(D->getIntegerTypeSourceInfo());
> >   if (!D->getIntegerTypeSourceInfo())
> > -    Writer.AddTypeRef(D->getIntegerType(), Record);
> > -  Writer.AddTypeRef(D->getPromotionType(), Record);
> > +    Record.AddTypeRef(D->getIntegerType());
> > +  Record.AddTypeRef(D->getPromotionType());
> >   Record.push_back(D->getNumPositiveBits());
> >   Record.push_back(D->getNumNegativeBits());
> >   Record.push_back(D->isScoped());
> >   Record.push_back(D->isScopedUsingClassTag());
> >   Record.push_back(D->isFixed());
> >   if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
> > -    Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
> > +    Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
> >     Record.push_back(MemberInfo->getTemplateSpecializationKind());
> > -    Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
> > +    Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
> >   } else {
> > -    Writer.AddDeclRef(nullptr, Record);
> > +    Record.AddDeclRef(nullptr);
> >   }
> >
> >   if (D->getDeclContext() == D->getLexicalDeclContext() &&
> > @@ -489,7 +501,7 @@ void ASTDeclWriter::VisitRecordDecl(Reco
> >
> > void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddTypeRef(D->getType(), Record);
> > +  Record.AddTypeRef(D->getType());
> > }
> >
> > void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
> > @@ -497,23 +509,23 @@ void ASTDeclWriter::VisitEnumConstantDec
> >   Record.push_back(D->getInitExpr()? 1 : 0);
> >   if (D->getInitExpr())
> >     Writer.AddStmt(D->getInitExpr());
> > -  Writer.AddAPSInt(D->getInitVal(), Record);
> > +  Record.AddAPSInt(D->getInitVal());
> >
> >   Code = serialization::DECL_ENUM_CONSTANT;
> > }
> >
> > void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
> >   VisitValueDecl(D);
> > -  Writer.AddSourceLocation(D->getInnerLocStart(), Record);
> > +  Record.AddSourceLocation(D->getInnerLocStart());
> >   Record.push_back(D->hasExtInfo());
> >   if (D->hasExtInfo())
> > -    Writer.AddQualifierInfo(*D->getExtInfo(), Record);
> > +    Record.AddQualifierInfo(*D->getExtInfo());
> > }
> >
> > void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
> >   VisitRedeclarable(D);
> >   VisitDeclaratorDecl(D);
> > -  Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
> > +  Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
> >   Record.push_back(D->getIdentifierNamespace());
> >
> >   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
> > @@ -535,20 +547,20 @@ void ASTDeclWriter::VisitFunctionDecl(Fu
> >   Record.push_back(D->HasSkippedBody);
> >   Record.push_back(D->IsLateTemplateParsed);
> >   Record.push_back(D->getLinkageInternal());
> > -  Writer.AddSourceLocation(D->getLocEnd(), Record);
> > +  Record.AddSourceLocation(D->getLocEnd());
> >
> >   Record.push_back(D->getTemplatedKind());
> >   switch (D->getTemplatedKind()) {
> >   case FunctionDecl::TK_NonTemplate:
> >     break;
> >   case FunctionDecl::TK_FunctionTemplate:
> > -    Writer.AddDeclRef(D->getDescribedFunctionTemplate(), Record);
> > +    Record.AddDeclRef(D->getDescribedFunctionTemplate());
> >     break;
> >   case FunctionDecl::TK_MemberSpecialization: {
> >     MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
> > -    Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
> > +    Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
> >     Record.push_back(MemberInfo->getTemplateSpecializationKind());
> > -    Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
> > +    Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
> >     break;
> >   }
> >   case FunctionDecl::TK_FunctionTemplateSpecialization: {
> > @@ -557,11 +569,11 @@ void ASTDeclWriter::VisitFunctionDecl(Fu
> >
> >     RegisterTemplateSpecialization(FTSInfo->getTemplate(), D);
> >
> > -    Writer.AddDeclRef(FTSInfo->getTemplate(), Record);
> > +    Record.AddDeclRef(FTSInfo->getTemplate());
> >     Record.push_back(FTSInfo->getTemplateSpecializationKind());
> >
> >     // Template arguments.
> > -    Writer.AddTemplateArgumentList(FTSInfo->TemplateArguments, Record);
> > +    Record.AddTemplateArgumentList(FTSInfo->TemplateArguments);
> >
> >     // Template args as written.
> >     Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
> > @@ -569,20 +581,18 @@ void ASTDeclWriter::VisitFunctionDecl(Fu
> >       Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
> >       for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
> >              i!=e; ++i)
> > -        Writer.AddTemplateArgumentLoc((*FTSInfo->TemplateArgumentsAsWritten)[i],
> > -                                      Record);
> > -      Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc,
> > -                               Record);
> > -      Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc,
> > -                               Record);
> > +        Record.AddTemplateArgumentLoc(
> > +            (*FTSInfo->TemplateArgumentsAsWritten)[i]);
> > +      Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc);
> > +      Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc);
> >     }
> >
> > -    Writer.AddSourceLocation(FTSInfo->getPointOfInstantiation(), Record);
> > +    Record.AddSourceLocation(FTSInfo->getPointOfInstantiation());
> >
> >     if (D->isCanonicalDecl()) {
> >       // Write the template that contains the specializations set. We will
> >       // add a FunctionTemplateSpecializationInfo to it when reading.
> > -      Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record);
> > +      Record.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl());
> >     }
> >     break;
> >   }
> > @@ -593,21 +603,21 @@ void ASTDeclWriter::VisitFunctionDecl(Fu
> >     // Templates.
> >     Record.push_back(DFTSInfo->getNumTemplates());
> >     for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
> > -      Writer.AddDeclRef(DFTSInfo->getTemplate(i), Record);
> > +      Record.AddDeclRef(DFTSInfo->getTemplate(i));
> >
> >     // Templates args.
> >     Record.push_back(DFTSInfo->getNumTemplateArgs());
> >     for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
> > -      Writer.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i), Record);
> > -    Writer.AddSourceLocation(DFTSInfo->getLAngleLoc(), Record);
> > -    Writer.AddSourceLocation(DFTSInfo->getRAngleLoc(), Record);
> > +      Record.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i));
> > +    Record.AddSourceLocation(DFTSInfo->getLAngleLoc());
> > +    Record.AddSourceLocation(DFTSInfo->getRAngleLoc());
> >     break;
> >   }
> >   }
> >
> >   Record.push_back(D->param_size());
> >   for (auto P : D->params())
> > -    Writer.AddDeclRef(P, Record);
> > +    Record.AddDeclRef(P);
> >   Code = serialization::DECL_FUNCTION;
> > }
> >
> > @@ -620,8 +630,8 @@ void ASTDeclWriter::VisitObjCMethodDecl(
> >   Record.push_back(HasBodyStuff);
> >   if (HasBodyStuff) {
> >     Writer.AddStmt(D->getBody());
> > -    Writer.AddDeclRef(D->getSelfDecl(), Record);
> > -    Writer.AddDeclRef(D->getCmdDecl(), Record);
> > +    Record.AddDeclRef(D->getSelfDecl());
> > +    Record.AddDeclRef(D->getCmdDecl());
> >   }
> >   Record.push_back(D->isInstanceMethod());
> >   Record.push_back(D->isVariadic());
> > @@ -634,7 +644,7 @@ void ASTDeclWriter::VisitObjCMethodDecl(
> >   Record.push_back(D->HasRedeclaration);
> >   if (D->HasRedeclaration) {
> >     assert(Context.getObjCMethodRedeclaration(D));
> > -    Writer.AddDeclRef(Context.getObjCMethodRedeclaration(D), Record);
> > +    Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
> >   }
> >
> >   // FIXME: stable encoding for @required/@optional
> > @@ -642,19 +652,19 @@ void ASTDeclWriter::VisitObjCMethodDecl(
> >   // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway/nullability
> >   Record.push_back(D->getObjCDeclQualifier());
> >   Record.push_back(D->hasRelatedResultType());
> > -  Writer.AddTypeRef(D->getReturnType(), Record);
> > -  Writer.AddTypeSourceInfo(D->getReturnTypeSourceInfo(), Record);
> > -  Writer.AddSourceLocation(D->getLocEnd(), Record);
> > +  Record.AddTypeRef(D->getReturnType());
> > +  Record.AddTypeSourceInfo(D->getReturnTypeSourceInfo());
> > +  Record.AddSourceLocation(D->getLocEnd());
> >   Record.push_back(D->param_size());
> >   for (const auto *P : D->params())
> > -    Writer.AddDeclRef(P, Record);
> > +    Record.AddDeclRef(P);
> >
> >   Record.push_back(D->SelLocsKind);
> >   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
> >   SourceLocation *SelLocs = D->getStoredSelLocs();
> >   Record.push_back(NumStoredSelLocs);
> >   for (unsigned i = 0; i != NumStoredSelLocs; ++i)
> > -    Writer.AddSourceLocation(SelLocs[i], Record);
> > +    Record.AddSourceLocation(SelLocs[i]);
> >
> >   Code = serialization::DECL_OBJC_METHOD;
> > }
> > @@ -663,23 +673,23 @@ void ASTDeclWriter::VisitObjCTypeParamDe
> >   VisitTypedefNameDecl(D);
> >   Record.push_back(D->Variance);
> >   Record.push_back(D->Index);
> > -  Writer.AddSourceLocation(D->VarianceLoc, Record);
> > -  Writer.AddSourceLocation(D->ColonLoc, Record);
> > +  Record.AddSourceLocation(D->VarianceLoc);
> > +  Record.AddSourceLocation(D->ColonLoc);
> >
> >   Code = serialization::DECL_OBJC_TYPE_PARAM;
> > }
> >
> > void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddSourceLocation(D->getAtStartLoc(), Record);
> > -  Writer.AddSourceRange(D->getAtEndRange(), Record);
> > +  Record.AddSourceLocation(D->getAtStartLoc());
> > +  Record.AddSourceRange(D->getAtEndRange());
> >   // Abstract class (no need to define a stable serialization::DECL code).
> > }
> >
> > void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
> >   VisitRedeclarable(D);
> >   VisitObjCContainerDecl(D);
> > -  Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
> > +  Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
> >   AddObjCTypeParamList(D->TypeParamList);
> >
> >   Record.push_back(D->isThisDeclarationADefinition());
> > @@ -687,16 +697,16 @@ void ASTDeclWriter::VisitObjCInterfaceDe
> >     // Write the DefinitionData
> >     ObjCInterfaceDecl::DefinitionData &Data = D->data();
> >
> > -    Writer.AddTypeSourceInfo(D->getSuperClassTInfo(), Record);
> > -    Writer.AddSourceLocation(D->getEndOfDefinitionLoc(), Record);
> > +    Record.AddTypeSourceInfo(D->getSuperClassTInfo());
> > +    Record.AddSourceLocation(D->getEndOfDefinitionLoc());
> >     Record.push_back(Data.HasDesignatedInitializers);
> >
> >     // Write out the protocols that are directly referenced by the @interface.
> >     Record.push_back(Data.ReferencedProtocols.size());
> >     for (const auto *P : D->protocols())
> > -      Writer.AddDeclRef(P, Record);
> > +      Record.AddDeclRef(P);
> >     for (const auto &PL : D->protocol_locs())
> > -      Writer.AddSourceLocation(PL, Record);
> > +      Record.AddSourceLocation(PL);
> >
> >     // Write out the protocols that are transitively referenced.
> >     Record.push_back(Data.AllReferencedProtocols.size());
> > @@ -704,7 +714,7 @@ void ASTDeclWriter::VisitObjCInterfaceDe
> >               P = Data.AllReferencedProtocols.begin(),
> >            PEnd = Data.AllReferencedProtocols.end();
> >          P != PEnd; ++P)
> > -      Writer.AddDeclRef(*P, Record);
> > +      Record.AddDeclRef(*P);
> >
> >
> >     if (ObjCCategoryDecl *Cat = D->getCategoryListRaw()) {
> > @@ -749,9 +759,9 @@ void ASTDeclWriter::VisitObjCProtocolDec
> >   if (D->isThisDeclarationADefinition()) {
> >     Record.push_back(D->protocol_size());
> >     for (const auto *I : D->protocols())
> > -      Writer.AddDeclRef(I, Record);
> > +      Record.AddDeclRef(I);
> >     for (const auto &PL : D->protocol_locs())
> > -      Writer.AddSourceLocation(PL, Record);
> > +      Record.AddSourceLocation(PL);
> >   }
> >
> >   Code = serialization::DECL_OBJC_PROTOCOL;
> > @@ -764,78 +774,78 @@ void ASTDeclWriter::VisitObjCAtDefsField
> >
> > void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
> >   VisitObjCContainerDecl(D);
> > -  Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
> > -  Writer.AddSourceLocation(D->getIvarLBraceLoc(), Record);
> > -  Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record);
> > -  Writer.AddDeclRef(D->getClassInterface(), Record);
> > +  Record.AddSourceLocation(D->getCategoryNameLoc());
> > +  Record.AddSourceLocation(D->getIvarLBraceLoc());
> > +  Record.AddSourceLocation(D->getIvarRBraceLoc());
> > +  Record.AddDeclRef(D->getClassInterface());
> >   AddObjCTypeParamList(D->TypeParamList);
> >   Record.push_back(D->protocol_size());
> >   for (const auto *I : D->protocols())
> > -    Writer.AddDeclRef(I, Record);
> > +    Record.AddDeclRef(I);
> >   for (const auto &PL : D->protocol_locs())
> > -    Writer.AddSourceLocation(PL, Record);
> > +    Record.AddSourceLocation(PL);
> >   Code = serialization::DECL_OBJC_CATEGORY;
> > }
> >
> > void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddDeclRef(D->getClassInterface(), Record);
> > +  Record.AddDeclRef(D->getClassInterface());
> >   Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
> > }
> >
> > void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddSourceLocation(D->getAtLoc(), Record);
> > -  Writer.AddSourceLocation(D->getLParenLoc(), Record);
> > -  Writer.AddTypeRef(D->getType(), Record);
> > -  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
> > +  Record.AddSourceLocation(D->getAtLoc());
> > +  Record.AddSourceLocation(D->getLParenLoc());
> > +  Record.AddTypeRef(D->getType());
> > +  Record.AddTypeSourceInfo(D->getTypeSourceInfo());
> >   // FIXME: stable encoding
> >   Record.push_back((unsigned)D->getPropertyAttributes());
> >   Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
> >   // FIXME: stable encoding
> >   Record.push_back((unsigned)D->getPropertyImplementation());
> > -  Writer.AddDeclarationName(D->getGetterName(), Record);
> > -  Writer.AddDeclarationName(D->getSetterName(), Record);
> > -  Writer.AddDeclRef(D->getGetterMethodDecl(), Record);
> > -  Writer.AddDeclRef(D->getSetterMethodDecl(), Record);
> > -  Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
> > +  Record.AddDeclarationName(D->getGetterName());
> > +  Record.AddDeclarationName(D->getSetterName());
> > +  Record.AddDeclRef(D->getGetterMethodDecl());
> > +  Record.AddDeclRef(D->getSetterMethodDecl());
> > +  Record.AddDeclRef(D->getPropertyIvarDecl());
> >   Code = serialization::DECL_OBJC_PROPERTY;
> > }
> >
> > void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
> >   VisitObjCContainerDecl(D);
> > -  Writer.AddDeclRef(D->getClassInterface(), Record);
> > +  Record.AddDeclRef(D->getClassInterface());
> >   // Abstract class (no need to define a stable serialization::DECL code).
> > }
> >
> > void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
> >   VisitObjCImplDecl(D);
> > -  Writer.AddIdentifierRef(D->getIdentifier(), Record);
> > -  Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
> > +  Record.AddIdentifierRef(D->getIdentifier());
> > +  Record.AddSourceLocation(D->getCategoryNameLoc());
> >   Code = serialization::DECL_OBJC_CATEGORY_IMPL;
> > }
> >
> > void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
> >   VisitObjCImplDecl(D);
> > -  Writer.AddDeclRef(D->getSuperClass(), Record);
> > -  Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
> > -  Writer.AddSourceLocation(D->getIvarLBraceLoc(), Record);
> > -  Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record);
> > +  Record.AddDeclRef(D->getSuperClass());
> > +  Record.AddSourceLocation(D->getSuperClassLoc());
> > +  Record.AddSourceLocation(D->getIvarLBraceLoc());
> > +  Record.AddSourceLocation(D->getIvarRBraceLoc());
> >   Record.push_back(D->hasNonZeroConstructors());
> >   Record.push_back(D->hasDestructors());
> >   Record.push_back(D->NumIvarInitializers);
> >   if (D->NumIvarInitializers)
> > -    Writer.AddCXXCtorInitializersRef(
> > -        llvm::makeArrayRef(D->init_begin(), D->init_end()), Record);
> > +    Record.AddCXXCtorInitializersRef(
> > +        llvm::makeArrayRef(D->init_begin(), D->init_end()));
> >   Code = serialization::DECL_OBJC_IMPLEMENTATION;
> > }
> >
> > void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
> >   VisitDecl(D);
> > -  Writer.AddSourceLocation(D->getLocStart(), Record);
> > -  Writer.AddDeclRef(D->getPropertyDecl(), Record);
> > -  Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
> > -  Writer.AddSourceLocation(D->getPropertyIvarDeclLoc(), Record);
> > +  Record.AddSourceLocation(D->getLocStart());
> > +  Record.AddDeclRef(D->getPropertyDecl());
> > +  Record.AddDeclRef(D->getPropertyIvarDecl());
> > +  Record.AddSourceLocation(D->getPropertyIvarDeclLoc());
> >   Writer.AddStmt(D->getGetterCXXConstructor());
> >   Writer.AddStmt(D->getSetterCXXAssignment());
> >   Code = serialization::DECL_OBJC_PROPERTY_IMPL;
> > @@ -849,15 +859,14 @@ void ASTDeclWriter::VisitFieldDecl(Field
> >     Record.push_back(0);
> >   } else if (D->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) {
> >     Record.push_back(D->InitStorage.getInt() + 1);
> > -    Writer.AddTypeRef(
> > -        QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0),
> > -        Record);
> > +    Record.AddTypeRef(
> > +        QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0));
> >   } else {
> >     Record.push_back(D->InitStorage.getInt() + 1);
> >     Writer.AddStmt(static_cast<Expr *>(D->InitStorage.getPointer()));
> >   }
> >   if (!D->getDeclName())
> > -    Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record);
> > +    Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
> >
> >   if (D->getDeclContext() == D->getLexicalDeclContext() &&
> >       !D->hasAttrs() &&
> > @@ -880,8 +889,8 @@ void ASTDeclWriter::VisitFieldDecl(Field
> >
> > void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
> >   VisitDeclaratorDecl(D);
> > -  Writer.AddIdentifierRef(D->getGetterId(), Record);
> > -  Writer.AddIdentifierRef(D->getSetterId(), Record);
> > +  Record.AddIdentifierRef(D->getGetterId());
> > +  Record.AddIdentifierRef(D->getSetterId());
> >   Code = serialization::DECL_MS_PROPERTY;
> > }
> >
> > @@ -890,7 +899,7 @@ void ASTDeclWriter::VisitIndirectFieldDe
> >   Record.push_back(D->getChainingSize());
> >
> >   for (const auto *P : D->chain())
> > -    Writer.AddDeclRef(P, Record);
> > +    Record.AddDeclRef(P);
> >   Code = serialization::DECL_INDIRECTFIELD;
> > }
> >
> > @@ -923,13 +932,13 @@ void ASTDeclWriter::VisitVarDecl(VarDecl
> >   };
> >   if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) {
> >     Record.push_back(VarTemplate);
> > -    Writer.AddDeclRef(TemplD, Record);
> > +    Record.AddDeclRef(TemplD);
> >   } else if (MemberSpecializationInfo *SpecInfo
> >                = D->getMemberSpecializationInfo()) {
> >     Record.push_back(StaticDataMemberSpecialization);
> > -    Writer.AddDeclRef(SpecInfo->getInstantiatedFrom(), Record);
> > +    Record.AddDeclRef(SpecInfo->getInstantiatedFrom());
> >     Record.push_back(SpecInfo->getTemplateSpecializationKind());
> > -    Writer.AddSourceLocation(SpecInfo->getPointOfInstantiation(), Record);
> > +    Record.AddSourceLocation(SpecInfo->getPointOfInstantiation());
> >   } else {
> >     Record.push_back(VarNotTemplate);
> >   }
> > @@ -1015,7 +1024,7 @@ void ASTDeclWriter::VisitParmVarDecl(Par
> > void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
> >   VisitDecl(D);
> >   Writer.AddStmt(D->getAsmString());
> > -  Writer.AddSourceLocation(D->getRParenLoc(), Record);
> > +  Record.AddSourceLocation(D->getRParenLoc());
> >   Code = serialization::DECL_FILE_SCOPE_ASM;
> > }
> >
> > @@ -1027,18 +1036,18 @@ void ASTDeclWriter::VisitEmptyDecl(Empty
> > void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
> >   VisitDecl(D);
> >   Writer.AddStmt(D->getBody());
> > -  Writer.AddTypeSourceInfo(D->getSignatureAsWritten(), Record);
> > +  Record.AddTypeSourceInfo(D->getSignatureAsWritten());
> >   Record.push_back(D->param_size());
> >   for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
> >        P != PEnd; ++P)
> > -    Writer.AddDeclRef(*P, Record);
> > +    Record.AddDeclRef(*P);
> >   Record.push_back(D->isVariadic());
> >   Record.push_back(D->blockMissingReturnType());
> >   Record.push_back(D->isConversionFromLambda());
> >   Record.push_back(D->capturesCXXThis());
> >   Record.push_back(D->getNumCaptures());
> >   for (const auto &capture : D->captures()) {
> > -    Writer.AddDeclRef(capture.getVariable(), Record);
> > +    Record.AddDeclRef(capture.getVariable());
> >
> >     unsigned flags = 0;
> >     if (capture.isByRef()) flags |= 1;
> > @@ -1059,21 +1068,21 @@ void ASTDeclWriter::VisitCapturedDecl(Ca
> >   Record.push_back(CD->isNothrow() ? 1 : 0);
> >   // Body is stored by VisitCapturedStmt.
> >   for (unsigned I = 0; I < CD->getNumParams(); ++I)
> > -    Writer.AddDeclRef(CD->getParam(I), Record);
> > +    Record.AddDeclRef(CD->getParam(I));
> >   Code = serialization::DECL_CAPTURED;
> > }
> >
> > void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
> >   VisitDecl(D);
> >   Record.push_back(D->getLanguage());
> > -  Writer.AddSourceLocation(D->getExternLoc(), Record);
> > -  Writer.AddSourceLocation(D->getRBraceLoc(), Record);
> > +  Record.AddSourceLocation(D->getExternLoc());
> > +  Record.AddSourceLocation(D->getRBraceLoc());
> >   Code = serialization::DECL_LINKAGE_SPEC;
> > }
> >
> > void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddSourceLocation(D->getLocStart(), Record);
> > +  Record.AddSourceLocation(D->getLocStart());
> >   Code = serialization::DECL_LABEL;
> > }
> >
> > @@ -1082,11 +1091,11 @@ void ASTDeclWriter::VisitNamespaceDecl(N
> >   VisitRedeclarable(D);
> >   VisitNamedDecl(D);
> >   Record.push_back(D->isInline());
> > -  Writer.AddSourceLocation(D->getLocStart(), Record);
> > -  Writer.AddSourceLocation(D->getRBraceLoc(), Record);
> > +  Record.AddSourceLocation(D->getLocStart());
> > +  Record.AddSourceLocation(D->getRBraceLoc());
> >
> >   if (D->isOriginalNamespace())
> > -    Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
> > +    Record.AddDeclRef(D->getAnonymousNamespace());
> >   Code = serialization::DECL_NAMESPACE;
> >
> >   if (Writer.hasChain() && D->isAnonymousNamespace() &&
> > @@ -1107,56 +1116,56 @@ void ASTDeclWriter::VisitNamespaceDecl(N
> > void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
> >   VisitRedeclarable(D);
> >   VisitNamedDecl(D);
> > -  Writer.AddSourceLocation(D->getNamespaceLoc(), Record);
> > -  Writer.AddSourceLocation(D->getTargetNameLoc(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
> > -  Writer.AddDeclRef(D->getNamespace(), Record);
> > +  Record.AddSourceLocation(D->getNamespaceLoc());
> > +  Record.AddSourceLocation(D->getTargetNameLoc());
> > +  Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
> > +  Record.AddDeclRef(D->getNamespace());
> >   Code = serialization::DECL_NAMESPACE_ALIAS;
> > }
> >
> > void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddSourceLocation(D->getUsingLoc(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
> > -  Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
> > -  Writer.AddDeclRef(D->FirstUsingShadow.getPointer(), Record);
> > +  Record.AddSourceLocation(D->getUsingLoc());
> > +  Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
> > +  Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
> > +  Record.AddDeclRef(D->FirstUsingShadow.getPointer());
> >   Record.push_back(D->hasTypename());
> > -  Writer.AddDeclRef(Context.getInstantiatedFromUsingDecl(D), Record);
> > +  Record.AddDeclRef(Context.getInstantiatedFromUsingDecl(D));
> >   Code = serialization::DECL_USING;
> > }
> >
> > void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
> >   VisitRedeclarable(D);
> >   VisitNamedDecl(D);
> > -  Writer.AddDeclRef(D->getTargetDecl(), Record);
> > -  Writer.AddDeclRef(D->UsingOrNextShadow, Record);
> > -  Writer.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D), Record);
> > +  Record.AddDeclRef(D->getTargetDecl());
> > +  Record.AddDeclRef(D->UsingOrNextShadow);
> > +  Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D));
> >   Code = serialization::DECL_USING_SHADOW;
> > }
> >
> > void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
> >   VisitNamedDecl(D);
> > -  Writer.AddSourceLocation(D->getUsingLoc(), Record);
> > -  Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
> > -  Writer.AddDeclRef(D->getNominatedNamespace(), Record);
> > -  Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record);
> > +  Record.AddSourceLocation(D->getUsingLoc());
> > +  Record.AddSourceLocation(D->getNamespaceKeyLocation());
> > +  Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
> > +  Record.AddDeclRef(D->getNominatedNamespace());
> > +  Record.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()));
> >   Code = serialization::DECL_USING_DIRECTIVE;
> > }
> >
> > void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
> >   VisitValueDecl(D);
> > -  Writer.AddSourceLocation(D->getUsingLoc(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
> > -  Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
> > +  Record.AddSourceLocation(D->getUsingLoc());
> > +  Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
> > +  Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
> >   Code = serialization::DECL_UNRESOLVED_USING_VALUE;
> > }
> >
> > void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
> >                                                UnresolvedUsingTypenameDecl *D) {
> >   VisitTypeDecl(D);
> > -  Writer.AddSourceLocation(D->getTypenameLoc(), Record);
> > -  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
> > +  Record.AddSourceLocation(D->getTypenameLoc());
> > +  Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
> >   Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
> > }
> >
> > @@ -1168,25 +1177,25 @@ void ASTDeclWriter::VisitCXXRecordDecl(C
> >   };
> >   if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
> >     Record.push_back(CXXRecTemplate);
> > -    Writer.AddDeclRef(TemplD, Record);
> > +    Record.AddDeclRef(TemplD);
> >   } else if (MemberSpecializationInfo *MSInfo
> >                = D->getMemberSpecializationInfo()) {
> >     Record.push_back(CXXRecMemberSpecialization);
> > -    Writer.AddDeclRef(MSInfo->getInstantiatedFrom(), Record);
> > +    Record.AddDeclRef(MSInfo->getInstantiatedFrom());
> >     Record.push_back(MSInfo->getTemplateSpecializationKind());
> > -    Writer.AddSourceLocation(MSInfo->getPointOfInstantiation(), Record);
> > +    Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
> >   } else {
> >     Record.push_back(CXXRecNotTemplate);
> >   }
> >
> >   Record.push_back(D->isThisDeclarationADefinition());
> >   if (D->isThisDeclarationADefinition())
> > -    Writer.AddCXXDefinitionData(D, Record);
> > +    Record.AddCXXDefinitionData(D);
> >
> >   // Store (what we currently believe to be) the key function to avoid
> >   // deserializing every method so we can compute it.
> >   if (D->IsCompleteDefinition)
> > -    Writer.AddDeclRef(Context.getCurrentKeyFunction(D), Record);
> > +    Record.AddDeclRef(Context.getCurrentKeyFunction(D));
> >
> >   Code = serialization::DECL_CXX_RECORD;
> > }
> > @@ -1198,7 +1207,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(C
> >     for (CXXMethodDecl::method_iterator
> >            I = D->begin_overridden_methods(), E = D->end_overridden_methods();
> >            I != E; ++I)
> > -      Writer.AddDeclRef(*I, Record);
> > +      Record.AddDeclRef(*I);
> >   } else {
> >     // We only need to record overridden methods once for the canonical decl.
> >     Record.push_back(0);
> > @@ -1221,7 +1230,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(C
> > void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
> >   VisitCXXMethodDecl(D);
> >
> > -  Writer.AddDeclRef(D->getInheritedConstructor(), Record);
> > +  Record.AddDeclRef(D->getInheritedConstructor());
> >   Record.push_back(D->IsExplicitSpecified);
> >
> >   Code = serialization::DECL_CXX_CONSTRUCTOR;
> > @@ -1230,7 +1239,7 @@ void ASTDeclWriter::VisitCXXConstructorD
> > void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
> >   VisitCXXMethodDecl(D);
> >
> > -  Writer.AddDeclRef(D->getOperatorDelete(), Record);
> > +  Record.AddDeclRef(D->getOperatorDelete());
> >
> >   Code = serialization::DECL_CXX_DESTRUCTOR;
> > }
> > @@ -1247,11 +1256,11 @@ void ASTDeclWriter::VisitImportDecl(Impo
> >   ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs();
> >   Record.push_back(!IdentifierLocs.empty());
> >   if (IdentifierLocs.empty()) {
> > -    Writer.AddSourceLocation(D->getLocEnd(), Record);
> > +    Record.AddSourceLocation(D->getLocEnd());
> >     Record.push_back(1);
> >   } else {
> >     for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I)
> > -      Writer.AddSourceLocation(IdentifierLocs[I], Record);
> > +      Record.AddSourceLocation(IdentifierLocs[I]);
> >     Record.push_back(IdentifierLocs.size());
> >   }
> >   // Note: the number of source locations must always be the last element in
> > @@ -1261,7 +1270,7 @@ void ASTDeclWriter::VisitImportDecl(Impo
> >
> > void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
> >   VisitDecl(D);
> > -  Writer.AddSourceLocation(D->getColonLoc(), Record);
> > +  Record.AddSourceLocation(D->getColonLoc());
> >   Code = serialization::DECL_ACCESS_SPEC;
> > }
> >
> > @@ -1273,15 +1282,14 @@ void ASTDeclWriter::VisitFriendDecl(Frie
> >   bool hasFriendDecl = D->Friend.is<NamedDecl*>();
> >   Record.push_back(hasFriendDecl);
> >   if (hasFriendDecl)
> > -    Writer.AddDeclRef(D->getFriendDecl(), Record);
> > +    Record.AddDeclRef(D->getFriendDecl());
> >   else
> > -    Writer.AddTypeSourceInfo(D->getFriendType(), Record);
> > +    Record.AddTypeSourceInfo(D->getFriendType());
> >   for (unsigned i = 0; i < D->NumTPLists; ++i)
> > -    Writer.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i),
> > -                                    Record);
> > -  Writer.AddDeclRef(D->getNextFriend(), Record);
> > +    Record.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i));
> > +  Record.AddDeclRef(D->getNextFriend());
> >   Record.push_back(D->UnsupportedFriend);
> > -  Writer.AddSourceLocation(D->FriendLoc, Record);
> > +  Record.AddSourceLocation(D->FriendLoc);
> >   Code = serialization::DECL_FRIEND;
> > }
> >
> > @@ -1289,21 +1297,21 @@ void ASTDeclWriter::VisitFriendTemplateD
> >   VisitDecl(D);
> >   Record.push_back(D->getNumTemplateParameters());
> >   for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
> > -    Writer.AddTemplateParameterList(D->getTemplateParameterList(i), Record);
> > +    Record.AddTemplateParameterList(D->getTemplateParameterList(i));
> >   Record.push_back(D->getFriendDecl() != nullptr);
> >   if (D->getFriendDecl())
> > -    Writer.AddDeclRef(D->getFriendDecl(), Record);
> > +    Record.AddDeclRef(D->getFriendDecl());
> >   else
> > -    Writer.AddTypeSourceInfo(D->getFriendType(), Record);
> > -  Writer.AddSourceLocation(D->getFriendLoc(), Record);
> > +    Record.AddTypeSourceInfo(D->getFriendType());
> > +  Record.AddSourceLocation(D->getFriendLoc());
> >   Code = serialization::DECL_FRIEND_TEMPLATE;
> > }
> >
> > void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
> >   VisitNamedDecl(D);
> >
> > -  Writer.AddDeclRef(D->getTemplatedDecl(), Record);
> > -  Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
> > +  Record.AddDeclRef(D->getTemplatedDecl());
> > +  Record.AddTemplateParameterList(D->getTemplateParameters());
> > }
> >
> > void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
> > @@ -1313,7 +1321,7 @@ void ASTDeclWriter::VisitRedeclarableTem
> >   // getCommonPtr() can be used while this is still initializing.
> >   if (D->isFirstDecl()) {
> >     // This declaration owns the 'common' pointer, so serialize that data now.
> > -    Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
> > +    Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
> >     if (D->getInstantiatedFromMemberTemplate())
> >       Record.push_back(D->isMemberSpecialization());
> >   }
> > @@ -1340,28 +1348,27 @@ void ASTDeclWriter::VisitClassTemplateSp
> >                      ClassTemplatePartialSpecializationDecl *> InstFrom
> >     = D->getSpecializedTemplateOrPartial();
> >   if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
> > -    Writer.AddDeclRef(InstFromD, Record);
> > +    Record.AddDeclRef(InstFromD);
> >   } else {
> > -    Writer.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>(),
> > -                      Record);
> > -    Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
> > +    Record.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>());
> > +    Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
> >   }
> >
> > -  Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record);
> > -  Writer.AddSourceLocation(D->getPointOfInstantiation(), Record);
> > +  Record.AddTemplateArgumentList(&D->getTemplateArgs());
> > +  Record.AddSourceLocation(D->getPointOfInstantiation());
> >   Record.push_back(D->getSpecializationKind());
> >   Record.push_back(D->isCanonicalDecl());
> >
> >   if (D->isCanonicalDecl()) {
> >     // When reading, we'll add it to the folding set of the following template.
> > -    Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record);
> > +    Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
> >   }
> >
> >   // Explicit info.
> > -  Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);
> > +  Record.AddTypeSourceInfo(D->getTypeAsWritten());
> >   if (D->getTypeAsWritten()) {
> > -    Writer.AddSourceLocation(D->getExternLoc(), Record);
> > -    Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record);
> > +    Record.AddSourceLocation(D->getExternLoc());
> > +    Record.AddSourceLocation(D->getTemplateKeywordLoc());
> >   }
> >
> >   Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
> > @@ -1371,12 +1378,12 @@ void ASTDeclWriter::VisitClassTemplatePa
> >                                     ClassTemplatePartialSpecializationDecl *D) {
> >   VisitClassTemplateSpecializationDecl(D);
> >
> > -  Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
> > -  Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record);
> > +  Record.AddTemplateParameterList(D->getTemplateParameters());
> > +  Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
> >
> >   // These are read/set from/to the first declaration.
> >   if (D->getPreviousDecl() == nullptr) {
> > -    Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
> > +    Record.AddDeclRef(D->getInstantiatedFromMember());
> >     Record.push_back(D->isMemberSpecialization());
> >   }
> >
> > @@ -1400,28 +1407,27 @@ void ASTDeclWriter::VisitVarTemplateSpec
> >   llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
> >   InstFrom = D->getSpecializedTemplateOrPartial();
> >   if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
> > -    Writer.AddDeclRef(InstFromD, Record);
> > +    Record.AddDeclRef(InstFromD);
> >   } else {
> > -    Writer.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>(),
> > -                      Record);
> > -    Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
> > +    Record.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>());
> > +    Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
> >   }
> >
> >   // Explicit info.
> > -  Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);
> > +  Record.AddTypeSourceInfo(D->getTypeAsWritten());
> >   if (D->getTypeAsWritten()) {
> > -    Writer.AddSourceLocation(D->getExternLoc(), Record);
> > -    Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record);
> > +    Record.AddSourceLocation(D->getExternLoc());
> > +    Record.AddSourceLocation(D->getTemplateKeywordLoc());
> >   }
> >
> > -  Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record);
> > -  Writer.AddSourceLocation(D->getPointOfInstantiation(), Record);
> > +  Record.AddTemplateArgumentList(&D->getTemplateArgs());
> > +  Record.AddSourceLocation(D->getPointOfInstantiation());
> >   Record.push_back(D->getSpecializationKind());
> >   Record.push_back(D->isCanonicalDecl());
> >
> >   if (D->isCanonicalDecl()) {
> >     // When reading, we'll add it to the folding set of the following template.
> > -    Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record);
> > +    Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
> >   }
> >
> >   Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION;
> > @@ -1431,12 +1437,12 @@ void ASTDeclWriter::VisitVarTemplatePart
> >     VarTemplatePartialSpecializationDecl *D) {
> >   VisitVarTemplateSpecializationDecl(D);
> >
> > -  Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
> > -  Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record);
> > +  Record.AddTemplateParameterList(D->getTemplateParameters());
> > +  Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
> >
> >   // These are read/set from/to the first declaration.
> >   if (D->getPreviousDecl() == nullptr) {
> > -    Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
> > +    Record.AddDeclRef(D->getInstantiatedFromMember());
> >     Record.push_back(D->isMemberSpecialization());
> >   }
> >
> > @@ -1446,7 +1452,7 @@ void ASTDeclWriter::VisitVarTemplatePart
> > void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
> >                                     ClassScopeFunctionSpecializationDecl *D) {
> >   VisitDecl(D);
> > -  Writer.AddDeclRef(D->getSpecialization(), Record);
> > +  Record.AddDeclRef(D->getSpecialization());
> >   Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
> > }
> >
> > @@ -1468,7 +1474,7 @@ void ASTDeclWriter::VisitTemplateTypePar
> >                         !D->defaultArgumentWasInherited();
> >   Record.push_back(OwnsDefaultArg);
> >   if (OwnsDefaultArg)
> > -    Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
> > +    Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
> >
> >   Code = serialization::DECL_TEMPLATE_TYPE_PARM;
> > }
> > @@ -1487,8 +1493,8 @@ void ASTDeclWriter::VisitNonTypeTemplate
> >
> >   if (D->isExpandedParameterPack()) {
> >     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
> > -      Writer.AddTypeRef(D->getExpansionType(I), Record);
> > -      Writer.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I), Record);
> > +      Record.AddTypeRef(D->getExpansionType(I));
> > +      Record.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I));
> >     }
> >
> >     Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
> > @@ -1519,8 +1525,7 @@ void ASTDeclWriter::VisitTemplateTemplat
> >   if (D->isExpandedParameterPack()) {
> >     for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
> >          I != N; ++I)
> > -      Writer.AddTemplateParameterList(D->getExpansionTemplateParameters(I),
> > -                                      Record);
> > +      Record.AddTemplateParameterList(D->getExpansionTemplateParameters(I));
> >     Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
> >   } else {
> >     // Rest of TemplateTemplateParmDecl.
> > @@ -1529,7 +1534,7 @@ void ASTDeclWriter::VisitTemplateTemplat
> >                           !D->defaultArgumentWasInherited();
> >     Record.push_back(OwnsDefaultArg);
> >     if (OwnsDefaultArg)
> > -      Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
> > +      Record.AddTemplateArgumentLoc(D->getDefaultArgument());
> >     Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
> >   }
> > }
> > @@ -1544,7 +1549,7 @@ void ASTDeclWriter::VisitStaticAssertDec
> >   Writer.AddStmt(D->getAssertExpr());
> >   Record.push_back(D->isFailed());
> >   Writer.AddStmt(D->getMessage());
> > -  Writer.AddSourceLocation(D->getRParenLoc(), Record);
> > +  Record.AddSourceLocation(D->getRParenLoc());
> >   Code = serialization::DECL_STATIC_ASSERT;
> > }
> >
> > @@ -1601,7 +1606,7 @@ void ASTDeclWriter::VisitRedeclarable(Re
> >     assert(isRedeclarableDeclKind(DAsT->getKind()) &&
> >            "Not considered redeclarable?");
> >
> > -    Writer.AddDeclRef(First, Record);
> > +    Record.AddDeclRef(First);
> >
> >     // Write out a list of local redeclarations of this declaration if it's the
> >     // first local declaration in the chain.
> > @@ -1619,24 +1624,23 @@ void ASTDeclWriter::VisitRedeclarable(Re
> >
> >       // Collect the set of local redeclarations of this declaration, from
> >       // newest to oldest.
> > -      RecordData LocalRedecls;
> > +      ASTWriter::RecordData LocalRedecls;
> > +      ASTRecordWriter LocalRedeclWriter(Record, LocalRedecls);
> >       for (const Decl *Prev = FirstLocal->getMostRecentDecl();
> >            Prev != FirstLocal; Prev = Prev->getPreviousDecl())
> >         if (!Prev->isFromASTFile())
> > -          Writer.AddDeclRef(Prev, LocalRedecls);
> > +          LocalRedeclWriter.AddDeclRef(Prev);
> >
> >       // If we have any redecls, write them now as a separate record preceding
> >       // the declaration itself.
> >       if (LocalRedecls.empty())
> >         Record.push_back(0);
> >       else {
> > -        auto Start = Writer.Stream.GetCurrentBitNo();
> > -        Writer.Stream.EmitRecord(LOCAL_REDECLARATIONS, LocalRedecls);
> > -        AddLocalOffset(Start);
> > +        AddLocalOffset(LocalRedeclWriter.Emit(LOCAL_REDECLARATIONS));
> >       }
> >     } else {
> >       Record.push_back(0);
> > -      Writer.AddDeclRef(FirstLocal, Record);
> > +      Record.AddDeclRef(FirstLocal);
> >     }
> >
> >     // Make sure that we serialize both the previous and the most-recent
> > @@ -1663,10 +1667,10 @@ void ASTDeclWriter::VisitOMPThreadPrivat
> >
> > void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
> >   VisitValueDecl(D);
> > -  Writer.AddSourceLocation(D->getLocStart(), Record);
> > +  Record.AddSourceLocation(D->getLocStart());
> >   Writer.AddStmt(D->getCombiner());
> >   Writer.AddStmt(D->getInitializer());
> > -  Writer.AddDeclRef(D->getPrevDeclInScope(), Record);
> > +  Record.AddDeclRef(D->getPrevDeclInScope());
> >   Code = serialization::DECL_OMP_DECLARE_REDUCTION;
> > }
> >
> > @@ -2146,9 +2150,6 @@ void ASTWriter::WriteDecl(ASTContext &Co
> >   // Switch case IDs are per Decl.
> >   ClearSwitchCaseIDs();
> >
> > -  RecordData Record;
> > -  ASTDeclWriter W(*this, Context, Record);
> > -
> >   // Determine the ID for this declaration.
> >   serialization::DeclID ID;
> >   assert(!D->isFromASTFile() && "should not be emitting imported decl");
> > @@ -2173,38 +2174,34 @@ void ASTWriter::WriteDecl(ASTContext &Co
> >     VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
> >   }
> >
> > +  RecordData Record;
> > +  ASTDeclWriter W(*this, Context, Record);
> > +
> >   // Build a record for this declaration
> > -  Record.clear();
> > -  W.Code = (serialization::DeclCode)0;
> > -  W.AbbrevToUse = 0;
> >   W.Visit(D);
> >   if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
> >
> > -  unsigned Index = ID - FirstDeclID;
> > +  // Emit this declaration to the bitstream.
> > +  uint64_t Offset = W.Emit(D);
> >
> >   // Record the offset for this declaration
> >   SourceLocation Loc = D->getLocation();
> > +  unsigned Index = ID - FirstDeclID;
> >   if (DeclOffsets.size() == Index)
> > -    DeclOffsets.push_back(DeclOffset(Loc, Stream.GetCurrentBitNo()));
> > +    DeclOffsets.push_back(DeclOffset(Loc, Offset));
> >   else if (DeclOffsets.size() < Index) {
> > +    // FIXME: Can/should this happen?
> >     DeclOffsets.resize(Index+1);
> >     DeclOffsets[Index].setLocation(Loc);
> > -    DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
> > +    DeclOffsets[Index].BitOffset = Offset;
> > +  } else {
> > +    llvm_unreachable("declarations should be emitted in ID order");
> >   }
> >
> >   SourceManager &SM = Context.getSourceManager();
> >   if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
> >     associateDeclWithFile(D, ID);
> >
> > -  if (!W.Code)
> > -    llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
> > -                            D->getDeclKindName() + "'");
> > -  Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
> > -
> > -  // 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, WritingModule))
> > @@ -2212,7 +2209,7 @@ void ASTWriter::WriteDecl(ASTContext &Co
> > }
> >
> > void ASTWriter::AddFunctionDefinition(const FunctionDecl *FD,
> > -                                      RecordData &Record) {
> > +                                      RecordDataImpl &Record) {
> >   ClearSwitchCaseIDs();
> >
> >   ASTDeclWriter W(*this, FD->getASTContext(), Record);
> >
> > Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=265195&r1=265194&r2=265195&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=265195&r1=265194&r2=265195&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Fri Apr  1 17:52:03 2016
> > @@ -112,7 +112,7 @@ void ASTStmtWriter::VisitLabelStmt(Label
> > void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
> >   VisitStmt(S);
> >   Record.push_back(S->getAttrs().size());
> > -  Writer.WriteAttributes(S->getAttrs(), Record);
> > +  Writer.AddAttributes(S->getAttrs(), Record);
> >   Writer.AddStmt(S->getSubStmt());
> >   Writer.AddSourceLocation(S->getAttrLoc(), Record);
> >   Code = serialization::STMT_ATTRIBUTED;
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160407/1685ed5c/attachment-0001.html>


More information about the cfe-commits mailing list