ASTWriterDecl.cpp revision 10620eb5164e31208fcbf0437cd79ae535ed0559
1ad5e73887052193afda72db8efcb812bd083a4a8John McCall//===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
25f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor//
35f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor//                     The LLVM Compiler Infrastructure
4b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson//
59234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// This file is distributed under the University of Illinois Open Source
69234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// License. See LICENSE.TXT for details.
79234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//
89234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//===----------------------------------------------------------------------===//
99234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//
109234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//  This file implements serialization for Declarations.
1131455256ae26cc7069111643ec4429ea564377daSean Hunt//
1231455256ae26cc7069111643ec4429ea564377daSean Hunt//===----------------------------------------------------------------------===//
1331455256ae26cc7069111643ec4429ea564377daSean Hunt
149234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "clang/Serialization/ASTWriter.h"
155f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor#include "ASTCommon.h"
165f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor#include "clang/AST/DeclVisitor.h"
179234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "clang/AST/DeclCXX.h"
18b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "clang/AST/DeclTemplate.h"
19b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "clang/AST/Expr.h"
20b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "clang/AST/DeclContextInternals.h"
219234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "llvm/ADT/Twine.h"
22b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "llvm/Bitcode/BitstreamWriter.h"
23b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "llvm/Support/ErrorHandling.h"
24b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlssonusing namespace clang;
259234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonusing namespace serialization;
26b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson
27b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson//===----------------------------------------------------------------------===//
284843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson// Declaration serialization
299234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//===----------------------------------------------------------------------===//
304843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson
314843e584b54460973b8445d38907bab0401ebb0cAnders Carlssonnamespace clang {
324843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson  class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
339234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson
34c6c91bc019ff7fa09f6570025ba011aad4c0d004Anders Carlsson    ASTWriter &Writer;
35984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson    ASTContext &Context;
369234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    typedef ASTWriter::RecordData RecordData;
37984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson    RecordData &Record;
38984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson
399234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson  public:
40984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson    serialization::DeclCode Code;
4191e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson    unsigned AbbrevToUse;
429234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson
4391e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson    ASTDeclWriter(ASTWriter &Writer, ASTContext &Context, RecordData &Record)
4491e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson      : Writer(Writer), Context(Context), Record(Record) {
452928c2107f2e0007f35fe1c224aab63535f1403dAnders Carlsson    }
4691e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson
47329749c1ec1ead3c41af52260f1203e4991b4e83Anders Carlsson    void Visit(Decl *D);
481b42c794481f6f958267e4ba913d74fef43161f6Anders Carlsson
491b42c794481f6f958267e4ba913d74fef43161f6Anders Carlsson    void VisitDecl(Decl *D);
50283a062a633d6e868aa2be319da812341fe73728Anders Carlsson    void VisitTranslationUnitDecl(TranslationUnitDecl *D);
51283a062a633d6e868aa2be319da812341fe73728Anders Carlsson    void VisitNamedDecl(NamedDecl *D);
522df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner    void VisitLabelDecl(LabelDecl *LD);
539234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitNamespaceDecl(NamespaceDecl *D);
542df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
557a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
567a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitTypeDecl(TypeDecl *D);
577a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitTypedefDecl(TypedefDecl *D);
589234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitTypeAliasDecl(TypeAliasDecl *D);
597a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
607a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitTagDecl(TagDecl *D);
619234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitEnumDecl(EnumDecl *D);
627a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitRecordDecl(RecordDecl *D);
637a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitCXXRecordDecl(CXXRecordDecl *D);
647a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitClassTemplateSpecializationDecl(
659234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson                                            ClassTemplateSpecializationDecl *D);
667a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitClassTemplatePartialSpecializationDecl(
677a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson                                     ClassTemplatePartialSpecializationDecl *D);
689234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
697a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitValueDecl(ValueDecl *D);
707a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitEnumConstantDecl(EnumConstantDecl *D);
717a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
727a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitDeclaratorDecl(DeclaratorDecl *D);
739234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitFunctionDecl(FunctionDecl *D);
747a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitCXXMethodDecl(CXXMethodDecl *D);
757a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitCXXConstructorDecl(CXXConstructorDecl *D);
769234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitCXXDestructorDecl(CXXDestructorDecl *D);
777a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitCXXConversionDecl(CXXConversionDecl *D);
787a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitFieldDecl(FieldDecl *D);
799234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitIndirectFieldDecl(IndirectFieldDecl *D);
807a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    void VisitVarDecl(VarDecl *D);
810e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    void VisitImplicitParamDecl(ImplicitParamDecl *D);
820e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    void VisitParmVarDecl(ParmVarDecl *D);
830e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
849234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitTemplateDecl(TemplateDecl *D);
850e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
860e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    void VisitClassTemplateDecl(ClassTemplateDecl *D);
879234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
880e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
89cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson    void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
909234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitUsingDecl(UsingDecl *D);
91cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson    void VisitUsingShadowDecl(UsingShadowDecl *D);
92cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson    void VisitLinkageSpecDecl(LinkageSpecDecl *D);
9303c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
9403c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    void VisitAccessSpecDecl(AccessSpecDecl *D);
9503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    void VisitFriendDecl(FriendDecl *D);
969234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    void VisitFriendTemplateDecl(FriendTemplateDecl *D);
977624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson    void VisitStaticAssertDecl(StaticAssertDecl *D);
987624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson    void VisitBlockDecl(BlockDecl *D);
997624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson
1007482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
1017482e247163978792654ca1a99913e19dd507e0aAnders Carlsson                          uint64_t VisibleOffset);
1027624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson    template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
1037624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson
104d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson
10503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    // FIXME: Put in the same order is DeclNodes.td?
10603c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    void VisitObjCMethodDecl(ObjCMethodDecl *D);
10703c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    void VisitObjCContainerDecl(ObjCContainerDecl *D);
10803c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
10903c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    void VisitObjCIvarDecl(ObjCIvarDecl *D);
1107624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson    void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
1117624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson    void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
1127624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson    void VisitObjCClassDecl(ObjCClassDecl *D);
1137482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
1147482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
1157482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    void VisitObjCImplDecl(ObjCImplDecl *D);
1167482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
1177482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
118d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson    void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
119d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson    void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
120d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson    void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
121d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  };
122d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson}
123d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson
124d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlssonvoid ASTDeclWriter::Visit(Decl *D) {
125d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  DeclVisitor<ASTDeclWriter>::Visit(D);
126d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson
127d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
128d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  // have been written. We want it last because we will not read it back when
129d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  // retrieving it from the AST, we'll just lazily set the offset.
1307482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1317482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    Record.push_back(FD->doesThisDeclarationHaveABody());
1327482e247163978792654ca1a99913e19dd507e0aAnders Carlsson    if (FD->doesThisDeclarationHaveABody())
133d58d6f778de936516d8815783f2e88348c41dce4Anders Carlsson      Writer.AddStmt(FD->getBody());
1347482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  }
1355cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson}
1365cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson
1375cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlssonvoid ASTDeclWriter::VisitDecl(Decl *D) {
1385cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson  Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
1395cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson  Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
1405cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson  Writer.AddSourceLocation(D->getLocation(), Record);
1415cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson  Record.push_back(D->isInvalidDecl());
142add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  Record.push_back(D->hasAttrs());
143add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  if (D->hasAttrs())
144add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson    Writer.WriteAttributes(D->getAttrs(), Record);
145add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  Record.push_back(D->isImplicit());
1468257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  Record.push_back(D->isUsed(false));
147add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  Record.push_back(D->isReferenced());
148add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  Record.push_back(D->getAccess());
149add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  Record.push_back(D->getPCHLevel());
150add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson}
151add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson
152ae3524866124021f3bc695886668254093c0793fAnders Carlssonvoid ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
153ae3524866124021f3bc695886668254093c0793fAnders Carlsson  VisitDecl(D);
154ae3524866124021f3bc695886668254093c0793fAnders Carlsson  Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
155ae3524866124021f3bc695886668254093c0793fAnders Carlsson  Code = serialization::DECL_TRANSLATION_UNIT;
156ae3524866124021f3bc695886668254093c0793fAnders Carlsson}
157ae3524866124021f3bc695886668254093c0793fAnders Carlsson
158ae3524866124021f3bc695886668254093c0793fAnders Carlssonvoid ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
159ae3524866124021f3bc695886668254093c0793fAnders Carlsson  VisitDecl(D);
1601668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  Writer.AddDeclarationName(D->getDeclName(), Record);
1611668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson}
1621668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1631668f2062b237ddb137f5d16388b3dea49651f85Anders Carlssonvoid ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
1641668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  VisitNamedDecl(D);
1651668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  Writer.AddSourceLocation(D->getLocStart(), Record);
1661668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
167aeb85374e92619b8e4ce92ac6e30756b5053a137Anders Carlsson}
1681668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1691668f2062b237ddb137f5d16388b3dea49651f85Anders Carlssonvoid ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
1701668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  VisitTypeDecl(D);
1711668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
1721668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  Code = serialization::DECL_TYPEDEF;
1731668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson}
1741668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1751668f2062b237ddb137f5d16388b3dea49651f85Anders Carlssonvoid ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
1761668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  VisitTypeDecl(D);
1770ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
1780ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson  Code = serialization::DECL_TYPEALIAS;
1790ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson}
1800ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson
1810ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlssonvoid ASTDeclWriter::VisitTagDecl(TagDecl *D) {
1820ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson  VisitTypeDecl(D);
1830ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson  VisitRedeclarable(D);
1840ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson  Record.push_back(D->getIdentifierNamespace());
18550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
18650755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Record.push_back(D->isDefinition());
18750755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Record.push_back(D->isEmbeddedInDeclarator());
18850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Writer.AddSourceLocation(D->getRBraceLoc(), Record);
18950755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Record.push_back(D->hasExtInfo());
19050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  if (D->hasExtInfo())
19150755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson    Writer.AddQualifierInfo(*D->getExtInfo(), Record);
19250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  else
19350755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson    Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record);
19450755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson}
19550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
19650755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlssonvoid ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
19750755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  VisitTagDecl(D);
19850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Writer.AddTypeSourceInfo(D->getIntegerTypeSourceInfo(), Record);
19950755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  if (!D->getIntegerTypeSourceInfo())
20050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson    Writer.AddTypeRef(D->getIntegerType(), Record);
20150755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Writer.AddTypeRef(D->getPromotionType(), Record);
20250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  Record.push_back(D->getNumPositiveBits());
203b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  Record.push_back(D->getNumNegativeBits());
204b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  Record.push_back(D->isScoped());
205b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  Record.push_back(D->isScopedUsingClassTag());
206b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  Record.push_back(D->isFixed());
207b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  Writer.AddDeclRef(D->getInstantiatedFromMemberEnum(), Record);
208b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  Code = serialization::DECL_ENUM;
209b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson}
210b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson
211b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlssonvoid ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
212c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson  VisitTagDecl(D);
2135c478cf2d54157062cd843737324e0d0df03a464Anders Carlsson  Record.push_back(D->hasFlexibleArrayMember());
214c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson  Record.push_back(D->isAnonymousStructOrUnion());
2155c478cf2d54157062cd843737324e0d0df03a464Anders Carlsson  Record.push_back(D->hasObjectMember());
216c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson  Code = serialization::DECL_RECORD;
217c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson}
218c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson
219c4355b6883382b85cda3b7337587784dabf3450bAnders Carlssonvoid ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
220c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson  VisitNamedDecl(D);
221c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson  Writer.AddTypeRef(D->getType(), Record);
2228e51a1f5da6ef4a1a168d14116c6eed3a578a263John McCall}
223c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson
224c4355b6883382b85cda3b7337587784dabf3450bAnders Carlssonvoid ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
225c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson  VisitValueDecl(D);
226c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson  Record.push_back(D->getInitExpr()? 1 : 0);
227a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson  if (D->getInitExpr())
228a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson    Writer.AddStmt(D->getInitExpr());
229a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson  Writer.AddAPSInt(D->getInitVal(), Record);
230a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson  Code = serialization::DECL_ENUM_CONSTANT;
231a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson}
232a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson
233e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonvoid ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
23458040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  VisitValueDecl(D);
23558040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  Writer.AddSourceLocation(D->getInnerLocStart(), Record);
23658040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  Record.push_back(D->hasExtInfo());
23758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  if (D->hasExtInfo())
23858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    Writer.AddQualifierInfo(*D->getExtInfo(), Record);
23958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
24058040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson}
24158040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson
24258040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlssonvoid ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
24358040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  VisitDeclaratorDecl(D);
24458040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  VisitRedeclarable(D);
24558040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson
24658040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
24758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  Record.push_back(D->getIdentifierNamespace());
24858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  Record.push_back(D->getTemplatedKind());
24958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  switch (D->getTemplatedKind()) {
250e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  default: assert(false && "Unhandled TemplatedKind!");
251e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    break;
252e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  case FunctionDecl::TK_NonTemplate:
2538f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor    break;
254e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  case FunctionDecl::TK_FunctionTemplate:
255e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    Writer.AddDeclRef(D->getDescribedFunctionTemplate(), Record);
256e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    break;
2578f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  case FunctionDecl::TK_MemberSpecialization: {
258e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
259e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
260e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    Record.push_back(MemberInfo->getTemplateSpecializationKind());
261e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
262e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    break;
2638f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  }
264e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  case FunctionDecl::TK_FunctionTemplateSpecialization: {
265e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    FunctionTemplateSpecializationInfo *
266e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson      FTSInfo = D->getTemplateSpecializationInfo();
2678f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor    Writer.AddDeclRef(FTSInfo->getTemplate(), Record);
268e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    Record.push_back(FTSInfo->getTemplateSpecializationKind());
269e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
270e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    // Template arguments.
271e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    Writer.AddTemplateArgumentList(FTSInfo->TemplateArguments, Record);
2728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor
273e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    // Template args as written.
274e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    Record.push_back(FTSInfo->TemplateArgumentsAsWritten != 0);
275e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    if (FTSInfo->TemplateArgumentsAsWritten) {
2768257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      Record.push_back(FTSInfo->TemplateArgumentsAsWritten->size());
2778257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->size(); i!=e; ++i)
2788257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson        Writer.AddTemplateArgumentLoc((*FTSInfo->TemplateArgumentsAsWritten)[i],
2798257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson                                      Record);
2808257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getLAngleLoc(),
2818257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson                               Record);
2828257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getRAngleLoc(),
2838257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson                               Record);
2848257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson    }
2858257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2868257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson    Writer.AddSourceLocation(FTSInfo->getPointOfInstantiation(), Record);
2878257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2888257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson    if (D->isCanonicalDecl()) {
2898257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      // Write the template that contains the specializations set. We will
2908257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      // add a FunctionTemplateSpecializationInfo to it when reading.
2918257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record);
2928257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson    }
2938257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson    break;
2948257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  }
2959e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson  case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
2969e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    DependentFunctionTemplateSpecializationInfo *
2979e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      DFTSInfo = D->getDependentSpecializationInfo();
2989e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson
2999e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    // Templates.
3009e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    Record.push_back(DFTSInfo->getNumTemplates());
3019e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
3029e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      Writer.AddDeclRef(DFTSInfo->getTemplate(i), Record);
3039e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson
3049e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    // Templates args.
3059e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    Record.push_back(DFTSInfo->getNumTemplateArgs());
3069e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
3079e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      Writer.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i), Record);
3088f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor    Writer.AddSourceLocation(DFTSInfo->getLAngleLoc(), Record);
3099e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    Writer.AddSourceLocation(DFTSInfo->getRAngleLoc(), Record);
3109e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    break;
311f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson  }
312f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson  }
313a9efbf009468f36df0bb66551677339055757d51Nuno Lopes
314a9efbf009468f36df0bb66551677339055757d51Nuno Lopes  // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
31531455256ae26cc7069111643ec4429ea564377daSean Hunt  // after everything else is written.
31631455256ae26cc7069111643ec4429ea564377daSean Hunt
31731455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->getStorageClass()); // FIXME: stable encoding
31831455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->getStorageClassAsWritten());
31931455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->IsInline);
32031455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->isInlineSpecified());
32131455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->isVirtualAsWritten());
32231455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->isPure());
32331455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->hasInheritedPrototype());
32431455256ae26cc7069111643ec4429ea564377daSean Hunt  Record.push_back(D->hasWrittenPrototype());
3251dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->isDeletedAsWritten());
3261dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->isTrivial());
3271dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->hasImplicitReturnZero());
3281dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Writer.AddSourceLocation(D->getLocEnd(), Record);
3291dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3301dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->param_size());
3311dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
3321dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall       P != PEnd; ++P)
3331dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    Writer.AddDeclRef(*P, Record);
3341dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Code = serialization::DECL_FUNCTION;
3351dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall}
3361dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3371dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCallvoid ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
3381dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  VisitNamedDecl(D);
3391dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  // FIXME: convert to LazyStmtPtr?
3401dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  // Unlike C/C++, method bodies will never be in header files.
3411dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  bool HasBodyStuff = D->getBody() != 0     ||
3421dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall                      D->getSelfDecl() != 0 || D->getCmdDecl() != 0;
3431dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(HasBodyStuff);
3441dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  if (HasBodyStuff) {
3451dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    Writer.AddStmt(D->getBody());
3461dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    Writer.AddDeclRef(D->getSelfDecl(), Record);
3471dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    Writer.AddDeclRef(D->getCmdDecl(), Record);
3481dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  }
3491dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->isInstanceMethod());
3501dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->isVariadic());
3511dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->isSynthesized());
3521dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->isDefined());
3531dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  // FIXME: stable encoding for @required/@optional
3541dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->getImplementationControl());
3551dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
3561dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->getObjCDeclQualifier());
3571dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Record.push_back(D->getNumSelectorArgs());
3581dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Writer.AddTypeRef(D->getResultType(), Record);
3592f27bf854f0519810b34afd209089cc75536b757John McCall  Writer.AddTypeSourceInfo(D->getResultTypeSourceInfo(), Record);
3602f27bf854f0519810b34afd209089cc75536b757John McCall  Writer.AddSourceLocation(D->getLocEnd(), Record);
3612f27bf854f0519810b34afd209089cc75536b757John McCall  Record.push_back(D->param_size());
3622f27bf854f0519810b34afd209089cc75536b757John McCall  for (ObjCMethodDecl::param_iterator P = D->param_begin(),
3632f27bf854f0519810b34afd209089cc75536b757John McCall                                   PEnd = D->param_end(); P != PEnd; ++P)
3642f27bf854f0519810b34afd209089cc75536b757John McCall    Writer.AddDeclRef(*P, Record);
3652f27bf854f0519810b34afd209089cc75536b757John McCall  Code = serialization::DECL_OBJC_METHOD;
366e1e342f4a96f132d8d7e802284417bd520f9f4f8John McCall}
3671dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
36832fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregorvoid ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
36932fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  VisitNamedDecl(D);
37032fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  Writer.AddSourceRange(D->getAtEndRange(), Record);
37132fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  // Abstract class (no need to define a stable serialization::DECL code).
3728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor}
37332fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor
37432fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregorvoid ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
375aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson  VisitObjCContainerDecl(D);
376aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson  Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
377aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson  Writer.AddDeclRef(D->getSuperClass(), Record);
378aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson
379ad5e73887052193afda72db8efcb812bd083a4a8John McCall  // Write out the protocols that are directly referenced by the @interface.
380ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Record.push_back(D->ReferencedProtocols.size());
381ad5e73887052193afda72db8efcb812bd083a4a8John McCall  for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
382ad5e73887052193afda72db8efcb812bd083a4a8John McCall         PEnd = D->protocol_end();
383ad5e73887052193afda72db8efcb812bd083a4a8John McCall       P != PEnd; ++P)
384ad5e73887052193afda72db8efcb812bd083a4a8John McCall    Writer.AddDeclRef(*P, Record);
385ad5e73887052193afda72db8efcb812bd083a4a8John McCall  for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
386ad5e73887052193afda72db8efcb812bd083a4a8John McCall         PLEnd = D->protocol_loc_end();
387ad5e73887052193afda72db8efcb812bd083a4a8John McCall       PL != PLEnd; ++PL)
388ad5e73887052193afda72db8efcb812bd083a4a8John McCall    Writer.AddSourceLocation(*PL, Record);
389ad5e73887052193afda72db8efcb812bd083a4a8John McCall
390ad5e73887052193afda72db8efcb812bd083a4a8John McCall  // Write out the protocols that are transitively referenced.
391ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Record.push_back(D->AllReferencedProtocols.size());
392ad5e73887052193afda72db8efcb812bd083a4a8John McCall  for (ObjCList<ObjCProtocolDecl>::iterator
393ad5e73887052193afda72db8efcb812bd083a4a8John McCall        P = D->AllReferencedProtocols.begin(),
394ad5e73887052193afda72db8efcb812bd083a4a8John McCall        PEnd = D->AllReferencedProtocols.end();
395ad5e73887052193afda72db8efcb812bd083a4a8John McCall       P != PEnd; ++P)
396ad5e73887052193afda72db8efcb812bd083a4a8John McCall    Writer.AddDeclRef(*P, Record);
397ad5e73887052193afda72db8efcb812bd083a4a8John McCall
398ad5e73887052193afda72db8efcb812bd083a4a8John McCall  // Write out the ivars.
399ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Record.push_back(D->ivar_size());
400ad5e73887052193afda72db8efcb812bd083a4a8John McCall  for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(),
401ad5e73887052193afda72db8efcb812bd083a4a8John McCall                                     IEnd = D->ivar_end(); I != IEnd; ++I)
4028f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor    Writer.AddDeclRef(*I, Record);
403ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Writer.AddDeclRef(D->getCategoryList(), Record);
404ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Record.push_back(D->isForwardDecl());
4058f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  Record.push_back(D->isImplicitInterfaceDecl());
406ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Writer.AddSourceLocation(D->getClassLoc(), Record);
407ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
408ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Writer.AddSourceLocation(D->getLocEnd(), Record);
409ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Code = serialization::DECL_OBJC_INTERFACE;
410ad5e73887052193afda72db8efcb812bd083a4a8John McCall}
411ad5e73887052193afda72db8efcb812bd083a4a8John McCall
412ad5e73887052193afda72db8efcb812bd083a4a8John McCallvoid ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
413ad5e73887052193afda72db8efcb812bd083a4a8John McCall  VisitFieldDecl(D);
414ad5e73887052193afda72db8efcb812bd083a4a8John McCall  // FIXME: stable encoding for @public/@private/@protected/@package
415ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Record.push_back(D->getAccessControl());
416ad5e73887052193afda72db8efcb812bd083a4a8John McCall  Record.push_back(D->getSynthesize());
417d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Code = serialization::DECL_OBJC_IVAR;
418d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola}
419d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
420d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindolavoid ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
421d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  VisitObjCContainerDecl(D);
422d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Record.push_back(D->isForwardDecl());
423d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Writer.AddSourceLocation(D->getLocEnd(), Record);
424d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Record.push_back(D->protocol_size());
425d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  for (ObjCProtocolDecl::protocol_iterator
426d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
427d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Writer.AddDeclRef(*I, Record);
428d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  for (ObjCProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
429d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola         PLEnd = D->protocol_loc_end();
430d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola       PL != PLEnd; ++PL)
431d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Writer.AddSourceLocation(*PL, Record);
432d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Code = serialization::DECL_OBJC_PROTOCOL;
433d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola}
434d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
435d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindolavoid ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
436d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  VisitFieldDecl(D);
437d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
438d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola}
439d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
440d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindolavoid ASTDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) {
441d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  VisitDecl(D);
442d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Record.push_back(D->size());
443d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
444d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Writer.AddDeclRef(I->getInterface(), Record);
445d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
446d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Writer.AddSourceLocation(I->getLocation(), Record);
447d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Code = serialization::DECL_OBJC_CLASS;
448d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola}
449d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
4508f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregorvoid ASTDeclWriter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
451d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  VisitDecl(D);
452d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  Record.push_back(D->protocol_size());
4537002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall  for (ObjCForwardProtocolDecl::protocol_iterator
454d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
455d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Writer.AddDeclRef(*I, Record);
4569b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  for (ObjCForwardProtocolDecl::protocol_loc_iterator
4579b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola         PL = D->protocol_loc_begin(), PLEnd = D->protocol_loc_end();
4589b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola       PL != PLEnd; ++PL)
4599b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    Writer.AddSourceLocation(*PL, Record);
4609b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  Code = serialization::DECL_OBJC_FORWARD_PROTOCOL;
4619b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola}
4629b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola
4639b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindolavoid ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
4649b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  VisitObjCContainerDecl(D);
4659b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  Writer.AddDeclRef(D->getClassInterface(), Record);
4669b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  Record.push_back(D->protocol_size());
4679b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  for (ObjCCategoryDecl::protocol_iterator
4689b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
4699b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    Writer.AddDeclRef(*I, Record);
4709b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  for (ObjCCategoryDecl::protocol_loc_iterator
471de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall         PL = D->protocol_loc_begin(), PLEnd = D->protocol_loc_end();
472de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall       PL != PLEnd; ++PL)
473de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall    Writer.AddSourceLocation(*PL, Record);
474de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall  Writer.AddDeclRef(D->getNextClassCategory(), Record);
475de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall  Record.push_back(D->hasSynthBitfield());
476de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall  Writer.AddSourceLocation(D->getAtLoc(), Record);
477de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall  Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
478de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall  Code = serialization::DECL_OBJC_CATEGORY;
479de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall}
48093296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson
48193296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlssonvoid ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
48293296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson  VisitNamedDecl(D);
48393296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson  Writer.AddDeclRef(D->getClassInterface(), Record);
48493296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson  Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
48593296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson}
48693296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson
48793296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlssonvoid ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
48893296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson  VisitNamedDecl(D);
48993296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson  Writer.AddSourceLocation(D->getAtLoc(), Record);
49093296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
49193296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson  // FIXME: stable encoding
492dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson  Record.push_back((unsigned)D->getPropertyAttributes());
493dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson  Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
494dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson  // FIXME: stable encoding
495dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson  Record.push_back((unsigned)D->getPropertyImplementation());
496dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson  Writer.AddDeclarationName(D->getGetterName(), Record);
497dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson  Writer.AddDeclarationName(D->getSetterName(), Record);
498b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall  Writer.AddDeclRef(D->getGetterMethodDecl(), Record);
499b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall  Writer.AddDeclRef(D->getSetterMethodDecl(), Record);
500b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall  Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
501b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall  Code = serialization::DECL_OBJC_PROPERTY;
502b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall}
503b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall
504b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCallvoid ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
505b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall  VisitObjCContainerDecl(D);
506b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall  Writer.AddDeclRef(D->getClassInterface(), Record);
507b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall  // Abstract class (no need to define a stable serialization::DECL code).
508b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall}
509b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall
510c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedmanvoid ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
511c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman  VisitObjCImplDecl(D);
512c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman  Writer.AddIdentifierRef(D->getIdentifier(), Record);
513c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman  Code = serialization::DECL_OBJC_CATEGORY_IMPL;
514c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman}
515c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman
516c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedmanvoid ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
517c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman  VisitObjCImplDecl(D);
518c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman  Writer.AddDeclRef(D->getSuperClass(), Record);
519c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman  Writer.AddCXXCtorInitializers(D->IvarInitializers, D->NumIvarInitializers,
520c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman                                Record);
5213dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  Record.push_back(D->hasSynthBitfield());
5223dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  Code = serialization::DECL_OBJC_IMPLEMENTATION;
5233dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall}
5243dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall
5253dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCallvoid ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
5263dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  VisitDecl(D);
5273dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  Writer.AddSourceLocation(D->getLocStart(), Record);
5283dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  Writer.AddDeclRef(D->getPropertyDecl(), Record);
5293dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
5303dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  Writer.AddSourceLocation(D->getPropertyIvarDeclLoc(), Record);
5313dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall  Writer.AddStmt(D->getGetterCXXConstructor());
5327121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall  Writer.AddStmt(D->getSetterCXXAssignment());
5337121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall  Code = serialization::DECL_OBJC_PROPERTY_IMPL;
5347121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall}
5357121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall
5367121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCallvoid ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
5377121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall  VisitDeclaratorDecl(D);
5387121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall  Record.push_back(D->isMutable());
5397121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall  Record.push_back(D->getBitWidth()? 1 : 0);
5407121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall  if (D->getBitWidth())
5417121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall    Writer.AddStmt(D->getBitWidth());
5427121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall  if (!D->getDeclName())
5436f615bc52bd5513019c32b378834a3c1b8425bf8John McCall    Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record);
5446f615bc52bd5513019c32b378834a3c1b8425bf8John McCall  Code = serialization::DECL_FIELD;
5456f615bc52bd5513019c32b378834a3c1b8425bf8John McCall}
5466f615bc52bd5513019c32b378834a3c1b8425bf8John McCall
5476f615bc52bd5513019c32b378834a3c1b8425bf8John McCallvoid ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
5486f615bc52bd5513019c32b378834a3c1b8425bf8John McCall  VisitValueDecl(D);
5496f615bc52bd5513019c32b378834a3c1b8425bf8John McCall  Record.push_back(D->getChainingSize());
5506f615bc52bd5513019c32b378834a3c1b8425bf8John McCall
5516f615bc52bd5513019c32b378834a3c1b8425bf8John McCall  for (IndirectFieldDecl::chain_iterator
5526f615bc52bd5513019c32b378834a3c1b8425bf8John McCall       P = D->chain_begin(),
5536f615bc52bd5513019c32b378834a3c1b8425bf8John McCall       PEnd = D->chain_end(); P != PEnd; ++P)
5546dbce19fdae4cfae4eb5f826284978e723a04e61John McCall    Writer.AddDeclRef(*P, Record);
5556f615bc52bd5513019c32b378834a3c1b8425bf8John McCall  Code = serialization::DECL_INDIRECTFIELD;
5566dbce19fdae4cfae4eb5f826284978e723a04e61John McCall}
5576dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
5586f615bc52bd5513019c32b378834a3c1b8425bf8John McCallvoid ASTDeclWriter::VisitVarDecl(VarDecl *D) {
5596f615bc52bd5513019c32b378834a3c1b8425bf8John McCall  VisitDeclaratorDecl(D);
5605e1e89b8af283af34943a477dc6378f1a641df26John McCall  VisitRedeclarable(D);
5615e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->getStorageClass()); // FIXME: stable encoding
5625e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->getStorageClassAsWritten());
5635e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->isThreadSpecified());
5645e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->hasCXXDirectInitializer());
5655e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->isExceptionVariable());
5665e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->isNRVOVariable());
5675e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->isCXXForRangeDecl());
5685e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(D->getInit() ? 1 : 0);
5695e1e89b8af283af34943a477dc6378f1a641df26John McCall  if (D->getInit())
5705e1e89b8af283af34943a477dc6378f1a641df26John McCall    Writer.AddStmt(D->getInit());
5715e1e89b8af283af34943a477dc6378f1a641df26John McCall
5725e1e89b8af283af34943a477dc6378f1a641df26John McCall  MemberSpecializationInfo *SpecInfo
5735e1e89b8af283af34943a477dc6378f1a641df26John McCall    = D->isStaticDataMember() ? D->getMemberSpecializationInfo() : 0;
5745e1e89b8af283af34943a477dc6378f1a641df26John McCall  Record.push_back(SpecInfo != 0);
5755e1e89b8af283af34943a477dc6378f1a641df26John McCall  if (SpecInfo) {
5765e1e89b8af283af34943a477dc6378f1a641df26John McCall    Writer.AddDeclRef(SpecInfo->getInstantiatedFrom(), Record);
5775e1e89b8af283af34943a477dc6378f1a641df26John McCall    Record.push_back(SpecInfo->getTemplateSpecializationKind());
5785e1e89b8af283af34943a477dc6378f1a641df26John McCall    Writer.AddSourceLocation(SpecInfo->getPointOfInstantiation(), Record);
5795e1e89b8af283af34943a477dc6378f1a641df26John McCall  }
5805e1e89b8af283af34943a477dc6378f1a641df26John McCall
5815e1e89b8af283af34943a477dc6378f1a641df26John McCall  Code = serialization::DECL_VAR;
5825e1e89b8af283af34943a477dc6378f1a641df26John McCall}
5835e1e89b8af283af34943a477dc6378f1a641df26John McCall
5845e1e89b8af283af34943a477dc6378f1a641df26John McCallvoid ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
5855e1e89b8af283af34943a477dc6378f1a641df26John McCall  VisitVarDecl(D);
5865e1e89b8af283af34943a477dc6378f1a641df26John McCall  Code = serialization::DECL_IMPLICIT_PARAM;
5875e1e89b8af283af34943a477dc6378f1a641df26John McCall}
5886dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
5896dbce19fdae4cfae4eb5f826284978e723a04e61John McCallvoid ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
5906dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  VisitVarDecl(D);
5916dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Record.push_back(D->isObjCMethodParameter());
5926dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Record.push_back(D->getFunctionScopeDepth());
5936dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Record.push_back(D->getFunctionScopeIndex());
5946dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
5956dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Record.push_back(D->isKNRPromoted());
5966dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Record.push_back(D->hasInheritedDefaultArg());
5976dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Record.push_back(D->hasUninstantiatedDefaultArg());
5986dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  if (D->hasUninstantiatedDefaultArg())
5996dbce19fdae4cfae4eb5f826284978e723a04e61John McCall    Writer.AddStmt(D->getUninstantiatedDefaultArg());
6006dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  Code = serialization::DECL_PARM_VAR;
6016dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
6026dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  // If the assumptions about the DECL_PARM_VAR abbrev are true, use it.  Here
6036dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  // we dynamically check for the properties that we optimize for, but don't
6046dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  // know are true of all PARM_VAR_DECLs.
6056dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  if (!D->getTypeSourceInfo() &&
6066dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      !D->hasAttrs() &&
6076dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      !D->isImplicit() &&
6086dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      !D->isUsed(false) &&
6096dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      D->getAccess() == AS_none &&
6106dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      D->getPCHLevel() == 0 &&
6116dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      D->getStorageClass() == 0 &&
6126dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      !D->hasCXXDirectInitializer() && // Can params have this ever?
6136dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      D->getFunctionScopeDepth() == 0 &&
6146dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      D->getObjCDeclQualifier() == 0 &&
6156dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      !D->isKNRPromoted() &&
6166dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      !D->hasInheritedDefaultArg() &&
6176dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      D->getInit() == 0 &&
6186dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      !D->hasUninstantiatedDefaultArg())  // No default expr.
6196dbce19fdae4cfae4eb5f826284978e723a04e61John McCall    AbbrevToUse = Writer.getParmVarDeclAbbrev();
6206dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
6216dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  // Check things we know are true of *every* PARM_VAR_DECL, which is more than
6226dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  // just us assuming it.
6236dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  assert(!D->isInvalidDecl() && "Shouldn't emit invalid decls");
6246dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread");
6256dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
6266dbce19fdae4cfae4eb5f826284978e723a04e61John McCall  assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
6277281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian  assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl");
6287281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian  assert(!D->isStaticDataMember() &&
6297281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian         "PARM_VAR_DECL can't be static data member");
6307281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian}
6317281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian
6327281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanianvoid ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
633e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson  VisitDecl(D);
634e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson  Writer.AddStmt(D->getAsmString());
635e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson  Writer.AddSourceLocation(D->getRParenLoc(), Record);
636e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson  Code = serialization::DECL_FILE_SCOPE_ASM;
637e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson}
638
639void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
640  VisitDecl(D);
641  Writer.AddStmt(D->getBody());
642  Writer.AddTypeSourceInfo(D->getSignatureAsWritten(), Record);
643  Record.push_back(D->param_size());
644  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
645       P != PEnd; ++P)
646    Writer.AddDeclRef(*P, Record);
647  Record.push_back(D->capturesCXXThis());
648  Record.push_back(D->getNumCaptures());
649  for (BlockDecl::capture_iterator
650         i = D->capture_begin(), e = D->capture_end(); i != e; ++i) {
651    const BlockDecl::Capture &capture = *i;
652    Writer.AddDeclRef(capture.getVariable(), Record);
653
654    unsigned flags = 0;
655    if (capture.isByRef()) flags |= 1;
656    if (capture.isNested()) flags |= 2;
657    if (capture.hasCopyExpr()) flags |= 4;
658    Record.push_back(flags);
659
660    if (capture.hasCopyExpr()) Writer.AddStmt(capture.getCopyExpr());
661  }
662
663  Code = serialization::DECL_BLOCK;
664}
665
666void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
667  VisitDecl(D);
668  Record.push_back(D->getLanguage());
669  Writer.AddSourceLocation(D->getExternLoc(), Record);
670  Writer.AddSourceLocation(D->getRBraceLoc(), Record);
671  Code = serialization::DECL_LINKAGE_SPEC;
672}
673
674void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
675  VisitNamedDecl(D);
676  Writer.AddSourceLocation(D->getLocStart(), Record);
677  Code = serialization::DECL_LABEL;
678}
679
680
681void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
682  VisitNamedDecl(D);
683  Record.push_back(D->isInline());
684  Writer.AddSourceLocation(D->getLocStart(), Record);
685  Writer.AddSourceLocation(D->getRBraceLoc(), Record);
686  Writer.AddDeclRef(D->getNextNamespace(), Record);
687
688  // Only write one reference--original or anonymous
689  Record.push_back(D->isOriginalNamespace());
690  if (D->isOriginalNamespace())
691    Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
692  else
693    Writer.AddDeclRef(D->getOriginalNamespace(), Record);
694  Code = serialization::DECL_NAMESPACE;
695
696  if (Writer.hasChain() && !D->isOriginalNamespace() &&
697      D->getOriginalNamespace()->getPCHLevel() > 0) {
698    NamespaceDecl *NS = D->getOriginalNamespace();
699    Writer.AddUpdatedDeclContext(NS);
700
701    // Make sure all visible decls are written. They will be recorded later.
702    NS->lookup(DeclarationName());
703    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(NS->getLookupPtr());
704    if (Map) {
705      for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
706           D != DEnd; ++D) {
707        DeclContext::lookup_result Result = D->second.getLookupResult();
708        while (Result.first != Result.second) {
709          Writer.GetDeclRef(*Result.first);
710          ++Result.first;
711        }
712      }
713    }
714  }
715
716  if (Writer.hasChain() && D->isAnonymousNamespace() && !D->getNextNamespace()){
717    // This is a most recent reopening of the anonymous namespace. If its parent
718    // is in a previous PCH (or is the TU), mark that parent for update, because
719    // the original namespace always points to the latest re-opening of its
720    // anonymous namespace.
721    Decl *Parent = cast<Decl>(
722        D->getParent()->getRedeclContext()->getPrimaryContext());
723    if (Parent->getPCHLevel() > 0) {
724      ASTWriter::UpdateRecord &Record = Writer.DeclUpdates[Parent];
725      Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
726      Writer.AddDeclRef(D, Record);
727    }
728  }
729}
730
731void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
732  VisitNamedDecl(D);
733  Writer.AddSourceLocation(D->getNamespaceLoc(), Record);
734  Writer.AddSourceLocation(D->getTargetNameLoc(), Record);
735  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
736  Writer.AddDeclRef(D->getNamespace(), Record);
737  Code = serialization::DECL_NAMESPACE_ALIAS;
738}
739
740void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
741  VisitNamedDecl(D);
742  Writer.AddSourceLocation(D->getUsingLocation(), Record);
743  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
744  Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
745  Writer.AddDeclRef(D->FirstUsingShadow, Record);
746  Record.push_back(D->isTypeName());
747  Writer.AddDeclRef(Context.getInstantiatedFromUsingDecl(D), Record);
748  Code = serialization::DECL_USING;
749}
750
751void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
752  VisitNamedDecl(D);
753  Writer.AddDeclRef(D->getTargetDecl(), Record);
754  Writer.AddDeclRef(D->UsingOrNextShadow, Record);
755  Writer.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D), Record);
756  Code = serialization::DECL_USING_SHADOW;
757}
758
759void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
760  VisitNamedDecl(D);
761  Writer.AddSourceLocation(D->getUsingLoc(), Record);
762  Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record);
763  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
764  Writer.AddDeclRef(D->getNominatedNamespace(), Record);
765  Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record);
766  Code = serialization::DECL_USING_DIRECTIVE;
767}
768
769void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
770  VisitValueDecl(D);
771  Writer.AddSourceLocation(D->getUsingLoc(), Record);
772  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
773  Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
774  Code = serialization::DECL_UNRESOLVED_USING_VALUE;
775}
776
777void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
778                                               UnresolvedUsingTypenameDecl *D) {
779  VisitTypeDecl(D);
780  Writer.AddSourceLocation(D->getTypenameLoc(), Record);
781  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
782  Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
783}
784
785void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
786  VisitRecordDecl(D);
787
788  CXXRecordDecl *DefinitionDecl = 0;
789  if (D->DefinitionData)
790    DefinitionDecl = D->DefinitionData->Definition;
791  Writer.AddDeclRef(DefinitionDecl, Record);
792  if (D == DefinitionDecl)
793    Writer.AddCXXDefinitionData(D, Record);
794
795  enum {
796    CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
797  };
798  if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
799    Record.push_back(CXXRecTemplate);
800    Writer.AddDeclRef(TemplD, Record);
801  } else if (MemberSpecializationInfo *MSInfo
802               = D->getMemberSpecializationInfo()) {
803    Record.push_back(CXXRecMemberSpecialization);
804    Writer.AddDeclRef(MSInfo->getInstantiatedFrom(), Record);
805    Record.push_back(MSInfo->getTemplateSpecializationKind());
806    Writer.AddSourceLocation(MSInfo->getPointOfInstantiation(), Record);
807  } else {
808    Record.push_back(CXXRecNotTemplate);
809  }
810
811  // Store the key function to avoid deserializing every method so we can
812  // compute it.
813  if (D->IsDefinition)
814    Writer.AddDeclRef(Context.getKeyFunction(D), Record);
815
816  Code = serialization::DECL_CXX_RECORD;
817}
818
819void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
820  VisitFunctionDecl(D);
821  Record.push_back(D->size_overridden_methods());
822  for (CXXMethodDecl::method_iterator
823         I = D->begin_overridden_methods(), E = D->end_overridden_methods();
824         I != E; ++I)
825    Writer.AddDeclRef(*I, Record);
826  Code = serialization::DECL_CXX_METHOD;
827}
828
829void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
830  VisitCXXMethodDecl(D);
831
832  Record.push_back(D->IsExplicitSpecified);
833  Record.push_back(D->ImplicitlyDefined);
834  Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers,
835                                Record);
836
837  Code = serialization::DECL_CXX_CONSTRUCTOR;
838}
839
840void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
841  VisitCXXMethodDecl(D);
842
843  Record.push_back(D->ImplicitlyDefined);
844  Writer.AddDeclRef(D->OperatorDelete, Record);
845
846  Code = serialization::DECL_CXX_DESTRUCTOR;
847}
848
849void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
850  VisitCXXMethodDecl(D);
851  Record.push_back(D->IsExplicitSpecified);
852  Code = serialization::DECL_CXX_CONVERSION;
853}
854
855void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
856  VisitDecl(D);
857  Writer.AddSourceLocation(D->getColonLoc(), Record);
858  Code = serialization::DECL_ACCESS_SPEC;
859}
860
861void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
862  VisitDecl(D);
863  Record.push_back(D->Friend.is<TypeSourceInfo*>());
864  if (D->Friend.is<TypeSourceInfo*>())
865    Writer.AddTypeSourceInfo(D->Friend.get<TypeSourceInfo*>(), Record);
866  else
867    Writer.AddDeclRef(D->Friend.get<NamedDecl*>(), Record);
868  Writer.AddDeclRef(D->getNextFriend(), Record);
869  Record.push_back(D->UnsupportedFriend);
870  Writer.AddSourceLocation(D->FriendLoc, Record);
871  Code = serialization::DECL_FRIEND;
872}
873
874void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
875  VisitDecl(D);
876  Record.push_back(D->getNumTemplateParameters());
877  for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
878    Writer.AddTemplateParameterList(D->getTemplateParameterList(i), Record);
879  Record.push_back(D->getFriendDecl() != 0);
880  if (D->getFriendDecl())
881    Writer.AddDeclRef(D->getFriendDecl(), Record);
882  else
883    Writer.AddTypeSourceInfo(D->getFriendType(), Record);
884  Writer.AddSourceLocation(D->getFriendLoc(), Record);
885  Code = serialization::DECL_FRIEND_TEMPLATE;
886}
887
888void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
889  VisitNamedDecl(D);
890
891  Writer.AddDeclRef(D->getTemplatedDecl(), Record);
892  Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
893}
894
895void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
896  // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
897  // getCommonPtr() can be used while this is still initializing.
898
899  Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
900  if (D->getPreviousDeclaration())
901    Writer.AddDeclRef(D->getFirstDeclaration(), Record);
902
903  if (D->getPreviousDeclaration() == 0) {
904    // This TemplateDecl owns the CommonPtr; write it.
905    assert(D->isCanonicalDecl());
906
907    Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
908    if (D->getInstantiatedFromMemberTemplate())
909      Record.push_back(D->isMemberSpecialization());
910
911    Writer.AddDeclRef(D->getCommonPtr()->Latest, Record);
912  } else {
913    RedeclarableTemplateDecl *First = D->getFirstDeclaration();
914    assert(First != D);
915    // If this is a most recent redeclaration that is pointed to by a first decl
916    // in a chained PCH, keep track of the association with the map so we can
917    // update the first decl during AST reading.
918    if (First->getMostRecentDeclaration() == D &&
919        First->getPCHLevel() > D->getPCHLevel()) {
920      assert(Writer.FirstLatestDecls.find(First)==Writer.FirstLatestDecls.end()
921             && "The latest is already set");
922      Writer.FirstLatestDecls[First] = D;
923    }
924  }
925
926  VisitTemplateDecl(D);
927  Record.push_back(D->getIdentifierNamespace());
928}
929
930void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
931  VisitRedeclarableTemplateDecl(D);
932
933  if (D->getPreviousDeclaration() == 0) {
934    typedef llvm::FoldingSet<ClassTemplateSpecializationDecl> CTSDSetTy;
935    CTSDSetTy &CTSDSet = D->getSpecializations();
936    Record.push_back(CTSDSet.size());
937    for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I) {
938      assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
939      Writer.AddDeclRef(&*I, Record);
940    }
941
942    typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> CTPSDSetTy;
943    CTPSDSetTy &CTPSDSet = D->getPartialSpecializations();
944    Record.push_back(CTPSDSet.size());
945    for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E=CTPSDSet.end(); I!=E; ++I) {
946      assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
947      Writer.AddDeclRef(&*I, Record);
948    }
949
950    // InjectedClassNameType is computed, no need to write it.
951  }
952  Code = serialization::DECL_CLASS_TEMPLATE;
953}
954
955void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
956                                           ClassTemplateSpecializationDecl *D) {
957  VisitCXXRecordDecl(D);
958
959  llvm::PointerUnion<ClassTemplateDecl *,
960                     ClassTemplatePartialSpecializationDecl *> InstFrom
961    = D->getSpecializedTemplateOrPartial();
962  Decl *InstFromD;
963  if (InstFrom.is<ClassTemplateDecl *>()) {
964    InstFromD = InstFrom.get<ClassTemplateDecl *>();
965    Writer.AddDeclRef(InstFromD, Record);
966  } else {
967    InstFromD = InstFrom.get<ClassTemplatePartialSpecializationDecl *>();
968    Writer.AddDeclRef(InstFromD, Record);
969    Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
970    InstFromD = cast<ClassTemplatePartialSpecializationDecl>(InstFromD)->
971                    getSpecializedTemplate();
972  }
973
974  // Explicit info.
975  Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);
976  if (D->getTypeAsWritten()) {
977    Writer.AddSourceLocation(D->getExternLoc(), Record);
978    Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record);
979  }
980
981  Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record);
982  Writer.AddSourceLocation(D->getPointOfInstantiation(), Record);
983  Record.push_back(D->getSpecializationKind());
984
985  if (D->isCanonicalDecl()) {
986    // When reading, we'll add it to the folding set of the following template.
987    Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record);
988  }
989
990  Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
991}
992
993void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
994                                    ClassTemplatePartialSpecializationDecl *D) {
995  VisitClassTemplateSpecializationDecl(D);
996
997  Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
998
999  Record.push_back(D->getNumTemplateArgsAsWritten());
1000  for (int i = 0, e = D->getNumTemplateArgsAsWritten(); i != e; ++i)
1001    Writer.AddTemplateArgumentLoc(D->getTemplateArgsAsWritten()[i], Record);
1002
1003  Record.push_back(D->getSequenceNumber());
1004
1005  // These are read/set from/to the first declaration.
1006  if (D->getPreviousDeclaration() == 0) {
1007    Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
1008    Record.push_back(D->isMemberSpecialization());
1009  }
1010
1011  Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
1012}
1013
1014void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1015  VisitRedeclarableTemplateDecl(D);
1016
1017  if (D->getPreviousDeclaration() == 0) {
1018    // This FunctionTemplateDecl owns the CommonPtr; write it.
1019
1020    // Write the function specialization declarations.
1021    Record.push_back(D->getSpecializations().size());
1022    for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
1023           I = D->getSpecializations().begin(),
1024           E = D->getSpecializations().end()   ; I != E; ++I) {
1025      assert(I->Function->isCanonicalDecl() &&
1026             "Expected only canonical decls in set");
1027      Writer.AddDeclRef(I->Function, Record);
1028    }
1029  }
1030  Code = serialization::DECL_FUNCTION_TEMPLATE;
1031}
1032
1033void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
1034  VisitTypeDecl(D);
1035
1036  Record.push_back(D->wasDeclaredWithTypename());
1037  Record.push_back(D->defaultArgumentWasInherited());
1038  Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
1039
1040  Code = serialization::DECL_TEMPLATE_TYPE_PARM;
1041}
1042
1043void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
1044  // For an expanded parameter pack, record the number of expansion types here
1045  // so that it's easier for
1046  if (D->isExpandedParameterPack())
1047    Record.push_back(D->getNumExpansionTypes());
1048
1049  VisitDeclaratorDecl(D);
1050  // TemplateParmPosition.
1051  Record.push_back(D->getDepth());
1052  Record.push_back(D->getPosition());
1053
1054  if (D->isExpandedParameterPack()) {
1055    for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
1056      Writer.AddTypeRef(D->getExpansionType(I), Record);
1057      Writer.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I), Record);
1058    }
1059
1060    Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
1061  } else {
1062    // Rest of NonTypeTemplateParmDecl.
1063    Record.push_back(D->isParameterPack());
1064    Record.push_back(D->getDefaultArgument() != 0);
1065    if (D->getDefaultArgument()) {
1066      Writer.AddStmt(D->getDefaultArgument());
1067      Record.push_back(D->defaultArgumentWasInherited());
1068    }
1069    Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
1070  }
1071}
1072
1073void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
1074  VisitTemplateDecl(D);
1075  // TemplateParmPosition.
1076  Record.push_back(D->getDepth());
1077  Record.push_back(D->getPosition());
1078  // Rest of TemplateTemplateParmDecl.
1079  Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
1080  Record.push_back(D->defaultArgumentWasInherited());
1081  Record.push_back(D->isParameterPack());
1082  Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
1083}
1084
1085void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
1086  VisitRedeclarableTemplateDecl(D);
1087  Code = serialization::DECL_TYPE_ALIAS_TEMPLATE;
1088}
1089
1090void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
1091  VisitDecl(D);
1092  Writer.AddStmt(D->getAssertExpr());
1093  Writer.AddStmt(D->getMessage());
1094  Writer.AddSourceLocation(D->getRParenLoc(), Record);
1095  Code = serialization::DECL_STATIC_ASSERT;
1096}
1097
1098/// \brief Emit the DeclContext part of a declaration context decl.
1099///
1100/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
1101/// block for this declaration context is stored. May be 0 to indicate
1102/// that there are no declarations stored within this context.
1103///
1104/// \param VisibleOffset the offset at which the DECL_CONTEXT_VISIBLE
1105/// block for this declaration context is stored. May be 0 to indicate
1106/// that there are no declarations visible from this context. Note
1107/// that this value will not be emitted for non-primary declaration
1108/// contexts.
1109void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
1110                                     uint64_t VisibleOffset) {
1111  Record.push_back(LexicalOffset);
1112  Record.push_back(VisibleOffset);
1113}
1114
1115template <typename T>
1116void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
1117  enum { NoRedeclaration = 0, PointsToPrevious, PointsToLatest };
1118  if (D->RedeclLink.getNext() == D) {
1119    Record.push_back(NoRedeclaration);
1120  } else {
1121    if (D->RedeclLink.NextIsPrevious()) {
1122      Record.push_back(PointsToPrevious);
1123      Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
1124      Writer.AddDeclRef(D->getFirstDeclaration(), Record);
1125    } else {
1126      Record.push_back(PointsToLatest);
1127      Writer.AddDeclRef(D->RedeclLink.getPointer(), Record);
1128    }
1129  }
1130
1131  T *First = D->getFirstDeclaration();
1132  T *ThisDecl = static_cast<T*>(D);
1133  // If this is a most recent redeclaration that is pointed to by a first decl
1134  // in a chained PCH, keep track of the association with the map so we can
1135  // update the first decl during AST reading.
1136  if (ThisDecl != First && First->getMostRecentDeclaration() == ThisDecl &&
1137      First->getPCHLevel() > ThisDecl->getPCHLevel()) {
1138    assert(Writer.FirstLatestDecls.find(First) == Writer.FirstLatestDecls.end()
1139           && "The latest is already set");
1140    Writer.FirstLatestDecls[First] = ThisDecl;
1141  }
1142}
1143
1144//===----------------------------------------------------------------------===//
1145// ASTWriter Implementation
1146//===----------------------------------------------------------------------===//
1147
1148void ASTWriter::WriteDeclsBlockAbbrevs() {
1149  using namespace llvm;
1150  // Abbreviation for DECL_PARM_VAR.
1151  BitCodeAbbrev *Abv = new BitCodeAbbrev();
1152  Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
1153
1154  // Decl
1155  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1156  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1157  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
1158  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl (!?)
1159  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1160  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1161  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
1162  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
1163  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
1164  Abv->Add(BitCodeAbbrevOp(0));                       // PCH level
1165
1166  // NamedDecl
1167  Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1168  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1169  // ValueDecl
1170  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1171  // DeclaratorDecl
1172  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
1173  Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
1174  Abv->Add(BitCodeAbbrevOp(serialization::PREDEF_TYPE_NULL_ID)); // InfoType
1175  // VarDecl
1176  Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
1177  Abv->Add(BitCodeAbbrevOp(0));                       // StorageClass
1178  Abv->Add(BitCodeAbbrevOp(0));                       // StorageClassAsWritten
1179  Abv->Add(BitCodeAbbrevOp(0));                       // isThreadSpecified
1180  Abv->Add(BitCodeAbbrevOp(0));                       // hasCXXDirectInitializer
1181  Abv->Add(BitCodeAbbrevOp(0));                       // isExceptionVariable
1182  Abv->Add(BitCodeAbbrevOp(0));                       // isNRVOVariable
1183  Abv->Add(BitCodeAbbrevOp(0));                       // isCXXForRangeDecl
1184  Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
1185  Abv->Add(BitCodeAbbrevOp(0));                   // HasMemberSpecializationInfo
1186  // ParmVarDecl
1187  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter
1188  Abv->Add(BitCodeAbbrevOp(0));                       // ScopeDepth
1189  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
1190  Abv->Add(BitCodeAbbrevOp(0));                       // ObjCDeclQualifier
1191  Abv->Add(BitCodeAbbrevOp(0));                       // KNRPromoted
1192  Abv->Add(BitCodeAbbrevOp(0));                       // HasInheritedDefaultArg
1193  Abv->Add(BitCodeAbbrevOp(0));                   // HasUninstantiatedDefaultArg
1194
1195  ParmVarDeclAbbrev = Stream.EmitAbbrev(Abv);
1196
1197  Abv = new BitCodeAbbrev();
1198  Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
1199  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1200  DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv);
1201
1202  Abv = new BitCodeAbbrev();
1203  Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
1204  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1205  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1206  DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
1207}
1208
1209/// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
1210/// consumers of the AST.
1211///
1212/// Such decls will always be deserialized from the AST file, so we would like
1213/// this to be as restrictive as possible. Currently the predicate is driven by
1214/// code generation requirements, if other clients have a different notion of
1215/// what is "required" then we may have to consider an alternate scheme where
1216/// clients can iterate over the top-level decls and get information on them,
1217/// without necessary deserializing them. We could explicitly require such
1218/// clients to use a separate API call to "realize" the decl. This should be
1219/// relatively painless since they would presumably only do it for top-level
1220/// decls.
1221static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
1222  // File scoped assembly or obj-c implementation must be seen.
1223  if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplementationDecl>(D))
1224    return true;
1225
1226  return Context.DeclMustBeEmitted(D);
1227}
1228
1229void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
1230  // Switch case IDs are per Decl.
1231  ClearSwitchCaseIDs();
1232
1233  RecordData Record;
1234  ASTDeclWriter W(*this, Context, Record);
1235
1236  // If this declaration is also a DeclContext, write blocks for the
1237  // declarations that lexically stored inside its context and those
1238  // declarations that are visible from its context. These blocks
1239  // are written before the declaration itself so that we can put
1240  // their offsets into the record for the declaration.
1241  uint64_t LexicalOffset = 0;
1242  uint64_t VisibleOffset = 0;
1243  DeclContext *DC = dyn_cast<DeclContext>(D);
1244  if (DC) {
1245    LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
1246    VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
1247  }
1248
1249  // Determine the ID for this declaration
1250  serialization::DeclID &IDR = DeclIDs[D];
1251  if (IDR == 0)
1252    IDR = NextDeclID++;
1253  serialization::DeclID ID = IDR;
1254
1255  if (ID < FirstDeclID) {
1256    // We're replacing a decl in a previous file.
1257    ReplacedDecls.push_back(std::make_pair(ID, Stream.GetCurrentBitNo()));
1258  } else {
1259    unsigned Index = ID - FirstDeclID;
1260
1261    // Record the offset for this declaration
1262    if (DeclOffsets.size() == Index)
1263      DeclOffsets.push_back(Stream.GetCurrentBitNo());
1264    else if (DeclOffsets.size() < Index) {
1265      DeclOffsets.resize(Index+1);
1266      DeclOffsets[Index] = Stream.GetCurrentBitNo();
1267    }
1268  }
1269
1270  // Build and emit a record for this declaration
1271  Record.clear();
1272  W.Code = (serialization::DeclCode)0;
1273  W.AbbrevToUse = 0;
1274  W.Visit(D);
1275  if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
1276
1277  if (!W.Code)
1278    llvm::report_fatal_error(llvm::StringRef("unexpected declaration kind '") +
1279                            D->getDeclKindName() + "'");
1280  Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
1281
1282  // Flush any expressions that were written as part of this declaration.
1283  FlushStmts();
1284
1285  // Flush C++ base specifiers, if there are any.
1286  FlushCXXBaseSpecifiers();
1287
1288  // Note "external" declarations so that we can add them to a record in the
1289  // AST file later.
1290  //
1291  // FIXME: This should be renamed, the predicate is much more complicated.
1292  if (isRequiredDecl(D, Context))
1293    ExternalDefinitions.push_back(ID);
1294}
1295