ASTWriter.cpp revision aa0cd85838f2a024e589ea4e8c2094130065af21
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===--- ASTWriter.cpp - AST File Writer ----------------------------------===//
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//                     The LLVM Compiler Infrastructure
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file is distributed under the University of Illinois Open Source
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// License. See LICENSE.TXT for details.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//  This file defines the ASTWriter class, which writes AST files.
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Serialization/ASTWriter.h"
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ASTCommon.h"
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Sema/Sema.h"
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Sema/IdentifierResolver.h"
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/ASTContext.h"
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/Decl.h"
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/DeclContextInternals.h"
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/DeclTemplate.h"
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/DeclFriend.h"
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/Expr.h"
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/ExprCXX.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/Type.h"
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/TypeLocVisitor.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Serialization/ASTReader.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Lex/MacroInfo.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Lex/PreprocessingRecord.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Lex/Preprocessor.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Lex/HeaderSearch.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/FileManager.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/FileSystemStatCache.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/OnDiskHashTable.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/SourceManager.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/SourceManagerInternals.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/TargetInfo.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/Version.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/VersionTuple.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/APFloat.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/APInt.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/StringExtras.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Bitcode/BitstreamWriter.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/FileSystem.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/MemoryBuffer.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/Path.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <algorithm>
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <cstdio>
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h>
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <utility>
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clang;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clang::serialization;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate <typename T, typename Allocator>
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic StringRef data(const std::vector<T, Allocator> &v) {
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (v.empty()) return StringRef();
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return StringRef(reinterpret_cast<const char*>(&v[0]),
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         sizeof(T) * v.size());
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate <typename T>
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic StringRef data(const SmallVectorImpl<T> &v) {
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return StringRef(reinterpret_cast<const char*>(v.data()),
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         sizeof(T) * v.size());
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Type serialization
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  class ASTTypeWriter {
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ASTWriter &Writer;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ASTWriter::RecordDataImpl &Record;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  public:
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /// \brief Type code that corresponds to the record generated.
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    TypeCode Code;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { }
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void VisitArrayType(const ArrayType *T);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void VisitFunctionType(const FunctionType *T);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void VisitTagType(const TagType *T);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T);
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ABSTRACT_TYPE(Class, Base)
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/TypeNodes.def"
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  };
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) {
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm_unreachable("Built-in types are never serialized");
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitComplexType(const ComplexType *T) {
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getElementType(), Record);
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_COMPLEX;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitPointerType(const PointerType *T) {
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getPointeeType(), Record);
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_POINTER;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getPointeeType(), Record);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_BLOCK_POINTER;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) {
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->isSpelledAsLValue());
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_LVALUE_REFERENCE;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_RVALUE_REFERENCE;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getPointeeType(), Record);
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(QualType(T->getClass(), 0), Record);
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_MEMBER_POINTER;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitArrayType(const ArrayType *T) {
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getElementType(), Record);
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getSizeModifier()); // FIXME: stable values
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayType(T);
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddAPInt(T->getSize(), Record);
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_CONSTANT_ARRAY;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayType(T);
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_INCOMPLETE_ARRAY;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayType(T);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(T->getLBracketLoc(), Record);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(T->getRBracketLoc(), Record);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddStmt(T->getSizeExpr());
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_VARIABLE_ARRAY;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitVectorType(const VectorType *T) {
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getElementType(), Record);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getNumElements());
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getVectorKind());
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_VECTOR;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) {
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitVectorType(T);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_EXT_VECTOR;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitFunctionType(const FunctionType *T) {
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getResultType(), Record);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FunctionType::ExtInfo C = T->getExtInfo();
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(C.getNoReturn());
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(C.getHasRegParm());
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(C.getRegParm());
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: need to stabilize encoding of calling convention...
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(C.getCC());
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(C.getProducesResult());
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitFunctionType(T);
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_FUNCTION_NO_PROTO;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitFunctionType(T);
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getNumArgs());
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I)
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddTypeRef(T->getArgType(I), Record);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->isVariadic());
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->hasTrailingReturn());
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getTypeQuals());
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getExceptionSpecType());
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (T->getExceptionSpecType() == EST_Dynamic) {
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(T->getNumExceptions());
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I)
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Writer.AddTypeRef(T->getExceptionType(I), Record);
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (T->getExceptionSpecType() == EST_ComputedNoexcept) {
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddStmt(T->getNoexceptExpr());
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (T->getExceptionSpecType() == EST_Uninstantiated) {
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddDeclRef(T->getExceptionSpecDecl(), Record);
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddDeclRef(T->getExceptionSpecTemplate(), Record);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_FUNCTION_PROTO;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddDeclRef(T->getDecl(), Record);
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_UNRESOLVED_USING;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitTypedefType(const TypedefType *T) {
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddDeclRef(T->getDecl(), Record);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!T->isCanonicalUnqualified() && "Invalid typedef ?");
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record);
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_TYPEDEF;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) {
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddStmt(T->getUnderlyingExpr());
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_TYPEOF_EXPR;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) {
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getUnderlyingType(), Record);
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_TYPEOF;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) {
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getUnderlyingType(), Record);
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddStmt(T->getUnderlyingExpr());
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_DECLTYPE;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitUnaryTransformType(const UnaryTransformType *T) {
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getBaseType(), Record);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getUnderlyingType(), Record);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getUTTKind());
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_UNARY_TRANSFORM;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitAutoType(const AutoType *T) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getDeducedType(), Record);
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_AUTO;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitTagType(const TagType *T) {
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->isDependentType());
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!T->isBeingDefined() &&
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "Cannot serialize in the middle of a type definition");
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitRecordType(const RecordType *T) {
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitTagType(T);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_RECORD;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitEnumType(const EnumType *T) {
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitTagType(T);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_ENUM;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitAttributedType(const AttributedType *T) {
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getModifiedType(), Record);
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getEquivalentType(), Record);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getAttrKind());
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_ATTRIBUTED;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitSubstTemplateTypeParmType(
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        const SubstTemplateTypeParmType *T) {
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getReplacementType(), Record);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_SUBST_TEMPLATE_TYPE_PARM;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitSubstTemplateTypeParmPackType(
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const SubstTemplateTypeParmPackType *T) {
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTemplateArgument(T->getArgumentPack(), Record);
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitTemplateSpecializationType(
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const TemplateSpecializationType *T) {
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->isDependentType());
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTemplateName(T->getTemplateName(), Record);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getNumArgs());
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end();
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ArgI != ArgE; ++ArgI)
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddTemplateArgument(*ArgI, Record);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->isTypeAlias() ? T->getAliasedType() :
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    T->isCanonicalUnqualified() ? QualType()
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                : T->getCanonicalTypeInternal(),
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    Record);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_TEMPLATE_SPECIALIZATION;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayType(T);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddStmt(T->getSizeExpr());
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceRange(T->getBracketsRange(), Record);
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_DEPENDENT_SIZED_ARRAY;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitDependentSizedExtVectorType(
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        const DependentSizedExtVectorType *T) {
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: Serialize this type (C++ only)
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm_unreachable("Cannot serialize dependent sized extended vector types");
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getDepth());
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getIndex());
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->isParameterPack());
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddDeclRef(T->getDecl(), Record);
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_TEMPLATE_TYPE_PARM;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitDependentNameType(const DependentNameType *T) {
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getKeyword());
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddIdentifierRef(T->getIdentifier(), Record);
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType()
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                : T->getCanonicalTypeInternal(),
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    Record);
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_DEPENDENT_NAME;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitDependentTemplateSpecializationType(
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const DependentTemplateSpecializationType *T) {
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getKeyword());
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddIdentifierRef(T->getIdentifier(), Record);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getNumArgs());
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DependentTemplateSpecializationType::iterator
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I = T->begin(), E = T->end(); I != E; ++I)
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddTemplateArgument(*I, Record);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitPackExpansionType(const PackExpansionType *T) {
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getPattern(), Record);
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (llvm::Optional<unsigned> NumExpansions = T->getNumExpansions())
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(*NumExpansions + 1);
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  else
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(0);
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_PACK_EXPANSION;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitParenType(const ParenType *T) {
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getInnerType(), Record);
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_PAREN;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getKeyword());
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getNamedType(), Record);
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_ELABORATED;
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getInjectedSpecializationType(), Record);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_INJECTED_CLASS_NAME;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_OBJC_INTERFACE;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getBaseType(), Record);
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(T->getNumProtocols());
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (ObjCObjectType::qual_iterator I = T->qual_begin(),
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       E = T->qual_end(); I != E; ++I)
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddDeclRef(*I, Record);
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_OBJC_OBJECT;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getPointeeType(), Record);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_OBJC_OBJECT_POINTER;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTTypeWriter::VisitAtomicType(const AtomicType *T) {
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeRef(T->getValueType(), Record);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Code = TYPE_ATOMIC;
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTWriter &Writer;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTWriter::RecordDataImpl &Record;
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    : Writer(Writer), Record(Record) { }
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ABSTRACT_TYPELOC(CLASS, PARENT)
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define TYPELOC(CLASS, PARENT) \
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/TypeLocNodes.def"
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void VisitArrayTypeLoc(ArrayTypeLoc TyLoc);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // nothing to do
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getBuiltinLoc(), Record);
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (TL.needsExtraLocalData()) {
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(TL.getWrittenTypeSpec());
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(TL.getWrittenSignSpec());
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(TL.getWrittenWidthSpec());
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(TL.hasModeAttr());
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getStarLoc(), Record);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getCaretLoc(), Record);
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getAmpLoc(), Record);
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getStarLoc(), Record);
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeSourceInfo(TL.getClassTInfo(), Record);
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLBracketLoc(), Record);
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRBracketLoc(), Record);
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TL.getSizeExpr() ? 1 : 0);
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (TL.getSizeExpr())
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddStmt(TL.getSizeExpr());
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayTypeLoc(TL);
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayTypeLoc(TL);
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayTypeLoc(TL);
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitDependentSizedArrayTypeLoc(
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            DependentSizedArrayTypeLoc TL) {
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitArrayTypeLoc(TL);
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        DependentSizedExtVectorTypeLoc TL) {
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLocalRangeBegin(), Record);
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLocalRangeEnd(), Record);
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TL.getTrailingReturn());
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddDeclRef(TL.getArg(i), Record);
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitFunctionTypeLoc(TL);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  VisitFunctionTypeLoc(TL);
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record);
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getKWLoc(), Record);
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record);
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getAttrNameLoc(), Record);
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (TL.hasAttrOperand()) {
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SourceRange range = TL.getAttrOperandParensRange();
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddSourceLocation(range.getBegin(), Record);
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddSourceLocation(range.getEnd(), Record);
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (TL.hasAttrExprOperand()) {
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Expr *operand = TL.getAttrExprOperand();
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(operand ? 1 : 0);
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (operand) Writer.AddStmt(operand);
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (TL.hasAttrEnumOperand()) {
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddSourceLocation(TL.getAttrEnumOperandLoc(), Record);
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            SubstTemplateTypeParmTypeLoc TL) {
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          SubstTemplateTypeParmPackTypeLoc TL) {
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitTemplateSpecializationTypeLoc(
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           TemplateSpecializationTypeLoc TL) {
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getTemplateKeywordLoc(), Record);
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(),
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      TL.getArgLoc(i).getLocInfo(), Record);
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getElaboratedKeywordLoc(), Record);
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getElaboratedKeywordLoc(), Record);
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       DependentTemplateSpecializationTypeLoc TL) {
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getElaboratedKeywordLoc(), Record);
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getTemplateKeywordLoc(), Record);
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(),
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      TL.getArgLoc(I).getLocInfo(), Record);
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getEllipsisLoc(), Record);
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getNameLoc(), Record);
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TL.hasBaseTypeAsWritten());
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getStarLoc(), Record);
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getKWLoc(), Record);
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// ASTWriter Implementation
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void EmitBlockID(unsigned ID, const char *Name,
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        llvm::BitstreamWriter &Stream,
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        ASTWriter::RecordDataImpl &Record) {
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(ID);
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the block name if present.
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Name == 0 || Name[0] == 0) return;
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (*Name)
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(*Name++);
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void EmitRecordID(unsigned ID, const char *Name,
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         llvm::BitstreamWriter &Stream,
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         ASTWriter::RecordDataImpl &Record) {
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(ID);
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (*Name)
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(*Name++);
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void AddStmtsExprs(llvm::BitstreamWriter &Stream,
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          ASTWriter::RecordDataImpl &Record) {
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_STOP);
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_NULL_PTR);
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_NULL);
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_COMPOUND);
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_CASE);
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_DEFAULT);
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_LABEL);
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_ATTRIBUTED);
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_IF);
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_SWITCH);
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_WHILE);
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_DO);
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_FOR);
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_GOTO);
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_INDIRECT_GOTO);
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_CONTINUE);
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_BREAK);
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_RETURN);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_DECL);
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_ASM);
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_PREDEFINED);
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_DECL_REF);
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_INTEGER_LITERAL);
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_FLOATING_LITERAL);
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_IMAGINARY_LITERAL);
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_STRING_LITERAL);
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CHARACTER_LITERAL);
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_PAREN);
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_UNARY_OPERATOR);
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_SIZEOF_ALIGN_OF);
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_ARRAY_SUBSCRIPT);
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CALL);
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_MEMBER);
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_BINARY_OPERATOR);
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR);
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CONDITIONAL_OPERATOR);
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_IMPLICIT_CAST);
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CSTYLE_CAST);
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_COMPOUND_LITERAL);
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_EXT_VECTOR_ELEMENT);
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_INIT_LIST);
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_DESIGNATED_INIT);
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_IMPLICIT_VALUE_INIT);
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_VA_ARG);
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_ADDR_LABEL);
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_STMT);
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CHOOSE);
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_GNU_NULL);
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_SHUFFLE_VECTOR);
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_BLOCK);
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_GENERIC_SELECTION);
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_STRING_LITERAL);
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_BOXED_EXPRESSION);
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_ARRAY_LITERAL);
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_DICTIONARY_LITERAL);
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_ENCODE);
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_SELECTOR_EXPR);
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_PROTOCOL_EXPR);
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_IVAR_REF_EXPR);
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_PROPERTY_REF_EXPR);
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_KVC_REF_EXPR);
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_MESSAGE_EXPR);
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_OBJC_FOR_COLLECTION);
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_OBJC_CATCH);
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_OBJC_FINALLY);
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_OBJC_AT_TRY);
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_OBJC_AT_SYNCHRONIZED);
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STMT_OBJC_AT_THROW);
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OBJC_BOOL_LITERAL);
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_OPERATOR_CALL);
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_CONSTRUCT);
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_STATIC_CAST);
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_DYNAMIC_CAST);
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_REINTERPRET_CAST);
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_CONST_CAST);
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_FUNCTIONAL_CAST);
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_USER_DEFINED_LITERAL);
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_BOOL_LITERAL);
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_NULL_PTR_LITERAL);
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_TYPEID_EXPR);
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_TYPEID_TYPE);
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_UUIDOF_EXPR);
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_UUIDOF_TYPE);
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_THIS);
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_THROW);
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_DEFAULT_ARG);
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_BIND_TEMPORARY);
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_SCALAR_VALUE_INIT);
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_NEW);
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_DELETE);
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_PSEUDO_DESTRUCTOR);
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_EXPR_WITH_CLEANUPS);
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_DEPENDENT_SCOPE_MEMBER);
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_DEPENDENT_SCOPE_DECL_REF);
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT);
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_UNRESOLVED_MEMBER);
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_UNRESOLVED_LOOKUP);
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_UNARY_TYPE_TRAIT);
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CXX_NOEXCEPT);
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_OPAQUE_VALUE);
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_BINARY_TYPE_TRAIT);
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_PACK_EXPANSION);
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_SIZEOF_PACK);
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXPR_CUDA_KERNEL_CALL);
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef RECORD
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteBlockInfoBlock() {
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3);
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record)
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // AST Top-Level Block.
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BLOCK(AST_BLOCK);
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(ORIGINAL_FILE_NAME);
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(ORIGINAL_FILE_ID);
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_OFFSET);
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OFFSET);
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(LANGUAGE_OPTIONS);
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(METADATA);
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(IDENTIFIER_OFFSET);
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(IDENTIFIER_TABLE);
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXTERNAL_DEFINITIONS);
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SPECIAL_TYPES);
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STATISTICS);
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TENTATIVE_DEFINITIONS);
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(UNUSED_FILESCOPED_DECLS);
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS);
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SELECTOR_OFFSETS);
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(METHOD_POOL);
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PP_COUNTER_VALUE);
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SOURCE_LOCATION_OFFSETS);
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SOURCE_LOCATION_PRELOADS);
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(STAT_CACHE);
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(EXT_VECTOR_DECLS);
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(VERSION_CONTROL_BRANCH_REVISION);
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PPD_ENTITIES_OFFSETS);
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(IMPORTS);
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(REFERENCED_SELECTOR_POOL);
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TU_UPDATE_LEXICAL);
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(LOCAL_REDECLARATIONS_MAP);
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SEMA_DECL_REFS);
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(WEAK_UNDECLARED_IDENTIFIERS);
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_REPLACEMENTS);
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(UPDATE_VISIBLE);
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_UPDATE_OFFSETS);
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_UPDATES);
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(CXX_BASE_SPECIFIER_OFFSETS);
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DIAG_PRAGMA_MAPPINGS);
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(CUDA_SPECIAL_DECL_REFS);
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(HEADER_SEARCH_TABLE);
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(ORIGINAL_PCH_DIR);
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(FP_PRAGMA_OPTIONS);
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(OPENCL_EXTENSIONS);
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DELEGATING_CTORS);
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(FILE_SOURCE_LOCATION_OFFSETS);
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(KNOWN_NAMESPACES);
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(MODULE_OFFSET_MAP);
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SOURCE_MANAGER_LINE_TABLE);
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(OBJC_CATEGORIES_MAP);
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(FILE_SORTED_DECLS);
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(IMPORTED_MODULES);
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(MERGED_DECLARATIONS);
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(LOCAL_REDECLARATIONS);
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(OBJC_CATEGORIES);
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // SourceManager Block.
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BLOCK(SOURCE_MANAGER_BLOCK);
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SM_SLOC_FILE_ENTRY);
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SM_SLOC_BUFFER_ENTRY);
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SM_SLOC_BUFFER_BLOB);
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(SM_SLOC_EXPANSION_ENTRY);
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Preprocessor Block.
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BLOCK(PREPROCESSOR_BLOCK);
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PP_MACRO_OBJECT_LIKE);
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PP_MACRO_FUNCTION_LIKE);
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PP_TOKEN);
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Decls and Types block.
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BLOCK(DECLTYPES_BLOCK);
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_EXT_QUAL);
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_COMPLEX);
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_POINTER);
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_BLOCK_POINTER);
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_LVALUE_REFERENCE);
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_RVALUE_REFERENCE);
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_MEMBER_POINTER);
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_CONSTANT_ARRAY);
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_INCOMPLETE_ARRAY);
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_VARIABLE_ARRAY);
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_VECTOR);
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_EXT_VECTOR);
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_FUNCTION_PROTO);
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_FUNCTION_NO_PROTO);
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_TYPEDEF);
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_TYPEOF_EXPR);
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_TYPEOF);
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_RECORD);
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_ENUM);
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_OBJC_INTERFACE);
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_OBJC_OBJECT);
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_OBJC_OBJECT_POINTER);
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_DECLTYPE);
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_ELABORATED);
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM);
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_UNRESOLVED_USING);
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_INJECTED_CLASS_NAME);
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_OBJC_OBJECT);
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_TEMPLATE_TYPE_PARM);
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_TEMPLATE_SPECIALIZATION);
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_DEPENDENT_NAME);
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION);
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_DEPENDENT_SIZED_ARRAY);
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_PAREN);
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_PACK_EXPANSION);
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_ATTRIBUTED);
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(TYPE_ATOMIC);
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_TYPEDEF);
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_ENUM);
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_RECORD);
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_ENUM_CONSTANT);
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_FUNCTION);
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_METHOD);
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_INTERFACE);
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_PROTOCOL);
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_IVAR);
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_AT_DEFS_FIELD);
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_CATEGORY);
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_CATEGORY_IMPL);
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_IMPLEMENTATION);
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_COMPATIBLE_ALIAS);
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_PROPERTY);
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_OBJC_PROPERTY_IMPL);
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_FIELD);
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_VAR);
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_IMPLICIT_PARAM);
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_PARM_VAR);
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_FILE_SCOPE_ASM);
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_BLOCK);
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CONTEXT_LEXICAL);
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CONTEXT_VISIBLE);
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_NAMESPACE);
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_NAMESPACE_ALIAS);
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_USING);
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_USING_SHADOW);
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_USING_DIRECTIVE);
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_UNRESOLVED_USING_VALUE);
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_UNRESOLVED_USING_TYPENAME);
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_LINKAGE_SPEC);
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CXX_RECORD);
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CXX_METHOD);
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CXX_CONSTRUCTOR);
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CXX_DESTRUCTOR);
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CXX_CONVERSION);
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_ACCESS_SPEC);
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_FRIEND);
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_FRIEND_TEMPLATE);
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CLASS_TEMPLATE);
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CLASS_TEMPLATE_SPECIALIZATION);
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION);
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_FUNCTION_TEMPLATE);
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_TEMPLATE_TYPE_PARM);
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_NON_TYPE_TEMPLATE_PARM);
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_TEMPLATE_TEMPLATE_PARM);
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_STATIC_ASSERT);
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_CXX_BASE_SPECIFIERS);
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_INDIRECTFIELD);
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK);
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Statements and Exprs can occur in the Decls and Types block.
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddStmtsExprs(Stream, Record);
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BLOCK(PREPROCESSOR_DETAIL_BLOCK);
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PPD_MACRO_EXPANSION);
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PPD_MACRO_DEFINITION);
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RECORD(PPD_INCLUSION_DIRECTIVE);
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef RECORD
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef BLOCK
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Adjusts the given filename to only write out the portion of the
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// filename that is not part of the system root directory.
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \param Filename the file name to adjust.
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// the returned filename will be adjusted by this system root.
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \returns either the original filename (if it needs no adjustment) or the
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// adjusted filename (which points into the @p Filename parameter).
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const char *
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgadjustFilenameForRelocatablePCH(const char *Filename, StringRef isysroot) {
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(Filename && "No file name to adjust?");
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (isysroot.empty())
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return Filename;
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Verify that the filename and the system root have the same prefix.
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned Pos = 0;
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (; Filename[Pos] && Pos < isysroot.size(); ++Pos)
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Filename[Pos] != isysroot[Pos])
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return Filename; // Prefixes don't match.
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // We hit the end of the filename before we hit the end of the system root.
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!Filename[Pos])
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return Filename;
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If the file name has a '/' at the current position, skip over the '/'.
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // We distinguish sysroot-based includes from absolute includes by the
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // absence of '/' at the beginning of sysroot-based includes.
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Filename[Pos] == '/')
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++Pos;
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Filename + Pos;
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the AST metadata (e.g., i686-apple-darwin9).
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot,
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              const std::string &OutputFile) {
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Metadata
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetInfo &Target = Context.getTargetInfo();
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(METADATA));
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Has errors
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(METADATA);
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(VERSION_MAJOR);
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(VERSION_MINOR);
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(CLANG_VERSION_MAJOR);
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(CLANG_VERSION_MINOR);
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(!isysroot.empty());
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(ASTHasCompilerErrors);
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const std::string &Triple = Target.getTriple().getTriple();
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple);
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Chain) {
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    serialization::ModuleManager &Mgr = Chain->getModuleManager();
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::SmallVector<char, 128> ModulePaths;
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (ModuleManager::ModuleIterator M = Mgr.begin(), MEnd = Mgr.end();
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         M != MEnd; ++M) {
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Skip modules that weren't directly imported.
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(*M)->isDirectlyImported())
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        continue;
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back((unsigned)(*M)->Kind); // FIXME: Stable encoding
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // FIXME: Write import location, once it matters.
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // FIXME: This writes the absolute path for AST files we depend on.
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const std::string &FileName = (*M)->FileName;
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(FileName.size());
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.append(FileName.begin(), FileName.end());
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(IMPORTS, Record);
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Original file name and file ID
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SourceManager &SM = Context.getSourceManager();
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev();
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE_NAME));
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev);
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallString<128> MainFilePath(MainFile->getName());
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::sys::fs::make_absolute(MainFilePath);
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const char *MainFileNameStr = MainFilePath.c_str();
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr,
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                      isysroot);
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    RecordData Record;
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(ORIGINAL_FILE_NAME);
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr);
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(SM.getMainFileID().getOpaqueValue());
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(ORIGINAL_FILE_ID, Record);
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Original PCH directory
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!OutputFile.empty() && OutputFile != "-") {
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR));
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallString<128> OutputPath(OutputFile);
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::sys::fs::make_absolute(OutputPath);
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    StringRef origDir = llvm::sys::path::parent_path(OutputPath);
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    RecordData Record;
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(ORIGINAL_PCH_DIR);
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir);
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Repository branch/version information.
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev();
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RepoAbbrev->Add(BitCodeAbbrevOp(VERSION_CONTROL_BRANCH_REVISION));
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev);
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(VERSION_CONTROL_BRANCH_REVISION);
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(RepoAbbrevCode, Record,
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            getClangFullRepositoryVersion());
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the LangOptions structure.
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LANGOPT(Name, Bits, Default, Description) \
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(LangOpts.Name);
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/LangOptions.def"
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(LangOpts.CurrentModule.size());
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.append(LangOpts.CurrentModule.begin(), LangOpts.CurrentModule.end());
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// stat cache Serialization
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Trait used for the on-disk hash table of stat cache results.
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ASTStatCacheTrait {
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef const char * key_type;
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef key_type key_type_ref;
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef struct stat data_type;
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef const data_type &data_type_ref;
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static unsigned ComputeHash(const char *path) {
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return llvm::HashString(path);
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::pair<unsigned,unsigned>
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    EmitKeyDataLength(raw_ostream& Out, const char *path,
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      data_type_ref Data) {
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned StrLen = strlen(path);
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, StrLen);
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned DataLen = 4 + 4 + 2 + 8 + 8;
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit8(Out, DataLen);
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return std::make_pair(StrLen + 1, DataLen);
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitKey(raw_ostream& Out, const char *path, unsigned KeyLen) {
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Out.write(path, KeyLen);
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitData(raw_ostream &Out, key_type_ref,
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                data_type_ref Data, unsigned DataLen) {
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    using namespace clang::io;
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint64_t Start = Out.tell(); (void)Start;
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Emit32(Out, (uint32_t) Data.st_ino);
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Emit32(Out, (uint32_t) Data.st_dev);
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Emit16(Out, (uint16_t) Data.st_mode);
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Emit64(Out, (uint64_t) Data.st_mtime);
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Emit64(Out, (uint64_t) Data.st_size);
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(Out.tell() - Start == DataLen && "Wrong data length");
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // end anonymous namespace
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the stat() system call cache to the AST file.
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) {
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build the on-disk hash table containing information about every
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // stat() call.
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  OnDiskChainedHashTableGenerator<ASTStatCacheTrait> Generator;
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned NumStatEntries = 0;
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                StatEnd = StatCalls.end();
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       Stat != StatEnd; ++Stat, ++NumStatEntries) {
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    StringRef Filename = Stat->first();
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Generator.insert(Filename.data(), Stat->second);
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create the on-disk hash table in a buffer.
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallString<4096> StatCacheData;
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint32_t BucketOffset;
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::raw_svector_ostream Out(StatCacheData);
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Make sure that no bucket is at offset 0
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit32(Out, 0);
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BucketOffset = Generator.Emit(Out);
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create a blob abbreviation
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(STAT_CACHE));
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev);
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the stat cache
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(STAT_CACHE);
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(BucketOffset);
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NumStatEntries);
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str());
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Source Manager Serialization
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Create an abbreviation for the SLocEntry that refers to a
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// file.
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY));
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FileEntry fields.
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // BufferOverridden
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24)); // FirstDeclIndex
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumDecls
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Stream.EmitAbbrev(Abbrev);
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Create an abbreviation for the SLocEntry that refers to a
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// buffer.
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) {
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY));
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Stream.EmitAbbrev(Abbrev);
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Create an abbreviation for the SLocEntry that refers to a
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// buffer's blob.
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) {
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_BLOB));
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Stream.EmitAbbrev(Abbrev);
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Create an abbreviation for the SLocEntry that refers to a macro
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// expansion.
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned CreateSLocExpansionAbbrev(llvm::BitstreamWriter &Stream) {
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_EXPANSION_ENTRY));
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Stream.EmitAbbrev(Abbrev);
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Trait used for the on-disk hash table of header search information.
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  class HeaderFileInfoTrait {
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ASTWriter &Writer;
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Keep track of the framework names we've used during serialization.
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallVector<char, 128> FrameworkStringData;
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::StringMap<unsigned> FrameworkNameOffset;
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  public:
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    HeaderFileInfoTrait(ASTWriter &Writer)
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      : Writer(Writer) { }
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typedef const char *key_type;
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typedef key_type key_type_ref;
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typedef HeaderFileInfo data_type;
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typedef const data_type &data_type_ref;
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    static unsigned ComputeHash(const char *path) {
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // The hash is based only on the filename portion of the key, so that the
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // reader can match based on filenames when symlinking or excess path
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // elements ("foo/../", "../") change the form of the name. However,
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // complete path is still the key.
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return llvm::HashString(llvm::sys::path::filename(path));
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    std::pair<unsigned,unsigned>
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    EmitKeyDataLength(raw_ostream& Out, const char *path,
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      data_type_ref Data) {
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned StrLen = strlen(path);
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit16(Out, StrLen);
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned DataLen = 1 + 2 + 4 + 4;
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit8(Out, DataLen);
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return std::make_pair(StrLen + 1, DataLen);
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void EmitKey(raw_ostream& Out, const char *path, unsigned KeyLen) {
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Out.write(path, KeyLen);
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void EmitData(raw_ostream &Out, key_type_ref,
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  data_type_ref Data, unsigned DataLen) {
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      using namespace clang::io;
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      uint64_t Start = Out.tell(); (void)Start;
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned char Flags = (Data.isImport << 5)
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          | (Data.isPragmaOnce << 4)
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          | (Data.DirInfo << 2)
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          | (Data.Resolved << 1)
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          | Data.IndexHeaderMapHeader;
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Emit8(Out, (uint8_t)Flags);
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Emit16(Out, (uint16_t) Data.NumIncludes);
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!Data.ControllingMacro)
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Emit32(Out, (uint32_t)Data.ControllingMacroID);
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Emit32(Out, (uint32_t)Writer.getIdentifierRef(Data.ControllingMacro));
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned Offset = 0;
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!Data.Framework.empty()) {
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // If this header refers into a framework, save the framework name.
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        llvm::StringMap<unsigned>::iterator Pos
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          = FrameworkNameOffset.find(Data.Framework);
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (Pos == FrameworkNameOffset.end()) {
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Offset = FrameworkStringData.size() + 1;
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          FrameworkStringData.append(Data.Framework.begin(),
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     Data.Framework.end());
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          FrameworkStringData.push_back(0);
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          FrameworkNameOffset[Data.Framework] = Offset;
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Offset = Pos->second;
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Emit32(Out, Offset);
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(Out.tell() - Start == DataLen && "Wrong data length");
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const char *strings_begin() const { return FrameworkStringData.begin(); }
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const char *strings_end() const { return FrameworkStringData.end(); }
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  };
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // end anonymous namespace
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the header search block for the list of files that
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \param HS The header search structure to save.
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \param Chain Whether we're creating a chained AST file.
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) {
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<const FileEntry *, 16> FilesByUID;
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (FilesByUID.size() > HS.header_file_size())
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FilesByUID.resize(HS.header_file_size());
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  HeaderFileInfoTrait GeneratorTrait(*this);
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<const char *, 4> SavedStrings;
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned NumHeaderSearchEntries = 0;
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const FileEntry *File = FilesByUID[UID];
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!File)
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Use HeaderSearch's getFileInfo to make sure we get the HeaderFileInfo
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // from the external source if it was not provided already.
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const HeaderFileInfo &HFI = HS.getFileInfo(File);
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (HFI.External && Chain)
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Turn the file name into an absolute path, if it isn't already.
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const char *Filename = File->getName();
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // If we performed any translation on the file name at all, we need to
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // save this string, since the generator will refer to it later.
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Filename != File->getName()) {
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Filename = strdup(Filename);
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SavedStrings.push_back(Filename);
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Generator.insert(Filename, HFI, GeneratorTrait);
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++NumHeaderSearchEntries;
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create the on-disk hash table in a buffer.
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallString<4096> TableData;
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint32_t BucketOffset;
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::raw_svector_ostream Out(TableData);
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Make sure that no bucket is at offset 0
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit32(Out, 0);
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BucketOffset = Generator.Emit(Out, GeneratorTrait);
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create a blob abbreviation
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE));
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned TableAbbrev = Stream.EmitAbbrev(Abbrev);
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the header search table
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(HEADER_SEARCH_TABLE);
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(BucketOffset);
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NumHeaderSearchEntries);
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TableData.size());
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end());
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData.str());
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Free all of the strings we had to duplicate.
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I)
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    free((void*)SavedStrings[I]);
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Writes the block containing the serialized form of the
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// source manager.
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// TODO: We should probably use an on-disk hash table (stored in a
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// blob), indexed based on the file name, so that we only create
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// entries for files that we actually need. In the common case (no
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// errors), we probably won't have to create file entries for any of
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// the files in the AST.
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        const Preprocessor &PP,
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        StringRef isysroot) {
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Enter the source manager block.
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 3);
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Abbreviations for the various kinds of source-location entries.
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream);
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned SLocExpansionAbbrv = CreateSLocExpansionAbbrev(Stream);
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write out the source location entry table. We skip the first
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // entry, which is always the same dummy entry.
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::vector<uint32_t> SLocEntryOffsets;
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write out the offsets of only source location file entries.
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // We will go through them in ASTReader::validateFileEntries().
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::vector<uint32_t> SLocFileEntryOffsets;
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData PreloadSLocs;
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SLocEntryOffsets.reserve(SourceMgr.local_sloc_entry_size() - 1);
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size();
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != N; ++I) {
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Get this source location entry.
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I);
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Record the offset of this source-location entry.
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SLocEntryOffsets.push_back(Stream.GetCurrentBitNo());
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Figure out which record code to use.
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned Code;
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (SLoc->isFile()) {
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const SrcMgr::ContentCache *Cache = SLoc->getFile().getContentCache();
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Cache->OrigEntry) {
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Code = SM_SLOC_FILE_ENTRY;
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        SLocFileEntryOffsets.push_back(Stream.GetCurrentBitNo());
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Code = SM_SLOC_BUFFER_ENTRY;
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Code = SM_SLOC_EXPANSION_ENTRY;
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Code);
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Starting offset of this entry within this module, so skip the dummy.
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(SLoc->getOffset() - 2);
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (SLoc->isFile()) {
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const SrcMgr::FileInfo &File = SLoc->getFile();
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(File.getIncludeLoc().getRawEncoding());
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(File.hasLineDirectives());
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const SrcMgr::ContentCache *Content = File.getContentCache();
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Content->OrigEntry) {
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert(Content->OrigEntry == Content->ContentsEntry &&
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               "Writing to AST an overridden file is not supported");
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // The source location entry is a file. The blob associated
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // with this entry is the file name.
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // Emit size/modification time for this file.
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(Content->OrigEntry->getSize());
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(Content->OrigEntry->getModificationTime());
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(Content->BufferOverridden);
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(File.NumCreatedFIDs);
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        FileDeclIDsTy::iterator FDI = FileDeclIDs.find(SLoc);
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (FDI != FileDeclIDs.end()) {
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.push_back(FDI->second->FirstDeclIndex);
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.push_back(FDI->second->DeclIDs.size());
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else {
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.push_back(0);
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.push_back(0);
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // Turn the file name into an absolute path, if it isn't already.
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        const char *Filename = Content->OrigEntry->getName();
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        SmallString<128> FilePath(Filename);
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // Ask the file manager to fixup the relative path for us. This will
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // honor the working directory.
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        SourceMgr.getFileManager().FixupRelativePath(FilePath);
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // FIXME: This call to make_absolute shouldn't be necessary, the
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // call to FixupRelativePath should always return an absolute path.
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        llvm::sys::fs::make_absolute(FilePath);
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Filename = FilePath.c_str();
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename);
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (Content->BufferOverridden) {
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.clear();
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.push_back(SM_SLOC_BUFFER_BLOB);
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          const llvm::MemoryBuffer *Buffer
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    StringRef(Buffer->getBufferStart(),
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              Buffer->getBufferSize() + 1));
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // The source location entry is a buffer. The blob associated
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // with this entry contains the contents of the buffer.
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // We add one to the size so that we capture the trailing NULL
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // that is required by llvm::MemoryBuffer::getMemBuffer (on
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // the reader side).
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        const llvm::MemoryBuffer *Buffer
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        const char *Name = Buffer->getBufferIdentifier();
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  StringRef(Name, strlen(Name) + 1));
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.clear();
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(SM_SLOC_BUFFER_BLOB);
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  StringRef(Buffer->getBufferStart(),
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  Buffer->getBufferSize() + 1));
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (strcmp(Name, "<built-in>") == 0) {
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          PreloadSLocs.push_back(SLocEntryOffsets.size());
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // The source location entry is a macro expansion.
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const SrcMgr::ExpansionInfo &Expansion = SLoc->getExpansion();
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Expansion.getSpellingLoc().getRawEncoding());
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Expansion.getExpansionLocStart().getRawEncoding());
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Expansion.isMacroArgExpansion() ? 0
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             : Expansion.getExpansionLocEnd().getRawEncoding());
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Compute the token length for this macro expansion.
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned NextOffset = SourceMgr.getNextLocalOffset();
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (I + 1 != N)
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        NextOffset = SourceMgr.getLocalSLocEntry(I + 1).getOffset();
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(NextOffset - SLoc->getOffset() - 1);
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecordWithAbbrev(SLocExpansionAbbrv, Record);
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (SLocEntryOffsets.empty())
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the source-location offsets table into the AST block. This
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // table is used for lazily loading source-location information.
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS));
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // total size
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev);
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(SOURCE_LOCATION_OFFSETS);
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(SLocEntryOffsets.size());
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(SourceMgr.getNextLocalOffset() - 1); // skip dummy
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets));
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev = new BitCodeAbbrev();
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(FILE_SOURCE_LOCATION_OFFSETS));
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned SLocFileOffsetsAbbrev = Stream.EmitAbbrev(Abbrev);
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(FILE_SOURCE_LOCATION_OFFSETS);
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(SLocFileEntryOffsets.size());
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(SLocFileOffsetsAbbrev, Record,
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            data(SLocFileEntryOffsets));
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the source location entry preloads array, telling the AST
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // reader which source locations entries it should load eagerly.
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs);
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the line table. It depends on remapping working, so it must come
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // after the source location offsets.
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (SourceMgr.hasLineTable()) {
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LineTableInfo &LineTable = SourceMgr.getLineTable();
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the file names
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(LineTable.getNumFilenames());
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Emit the file name
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *Filename = LineTable.getFilename(I);
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned FilenameLen = Filename? strlen(Filename) : 0;
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(FilenameLen);
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (FilenameLen)
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.insert(Record.end(), Filename, Filename + FilenameLen);
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the line entries
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         L != LEnd; ++L) {
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Only emit entries for local files.
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (L->first.ID < 0)
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        continue;
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Emit the file ID
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(L->first.ID);
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Emit the line entries
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(L->second.size());
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (std::vector<LineEntry>::iterator LE = L->second.begin(),
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         LEEnd = L->second.end();
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           LE != LEEnd; ++LE) {
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(LE->FileOffset);
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(LE->LineNo);
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(LE->FilenameID);
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back((unsigned)LE->FileKind);
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(LE->IncludeOffset);
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(SOURCE_MANAGER_LINE_TABLE, Record);
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Preprocessor Serialization
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int compareMacroDefinitions(const void *XPtr, const void *YPtr) {
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const std::pair<const IdentifierInfo *, MacroInfo *> &X =
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *(const std::pair<const IdentifierInfo *, MacroInfo *>*)XPtr;
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const std::pair<const IdentifierInfo *, MacroInfo *> &Y =
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *(const std::pair<const IdentifierInfo *, MacroInfo *>*)YPtr;
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return X.first->getName().compare(Y.first->getName());
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Writes the block containing the serialized form of the
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// preprocessor.
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (PPRec)
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    WritePreprocessorDetail(*PPRec);
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If the preprocessor __COUNTER__ value has been bumped, remember it.
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (PP.getCounterValue() != 0) {
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(PP.getCounterValue());
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(PP_COUNTER_VALUE, Record);
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Enter the preprocessor block.
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3);
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If the AST file contains __DATE__ or __TIME__ emit a warning about this.
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: use diagnostics subsystem for localization etc.
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (PP.SawDateOrTime())
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Loop over all the macro definitions that are live at the end of the file,
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // emitting each to the PP section.
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Construct the list of macro definitions that need to be serialized.
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2>
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MacrosToEmit;
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::SmallPtrSet<const IdentifierInfo*, 4> MacroDefinitionsSeen;
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0),
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    E = PP.macro_end(Chain == 0);
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != E; ++I) {
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const IdentifierInfo *Name = I->first;
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!IsModule || I->second->isPublic()) {
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MacroDefinitionsSeen.insert(Name);
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MacrosToEmit.push_back(std::make_pair(I->first, I->second));
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Sort the set of macro definitions that need to be serialized by the
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // name of the macro, to provide a stable ordering.
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::array_pod_sort(MacrosToEmit.begin(), MacrosToEmit.end(),
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       &compareMacroDefinitions);
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Resolve any identifiers that defined macros at the time they were
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // deserialized, adding them to the list of macros to emit (if appropriate).
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, N = DeserializedMacroNames.size(); I != N; ++I) {
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    IdentifierInfo *Name
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = const_cast<IdentifierInfo *>(DeserializedMacroNames[I]);
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Name->hasMacroDefinition() && MacroDefinitionsSeen.insert(Name))
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MacrosToEmit.push_back(std::make_pair(Name, PP.getMacroInfo(Name)));
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, N = MacrosToEmit.size(); I != N; ++I) {
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const IdentifierInfo *Name = MacrosToEmit[I].first;
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MacroInfo *MI = MacrosToEmit[I].second;
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!MI)
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Don't emit builtin macros like __LINE__ to the AST file unless they have
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // been redefined by the header (in which case they are not isBuiltinMacro).
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Also skip macros from a AST file if we're chaining.
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // FIXME: There is a (probably minor) optimization we could do here, if
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // the macro comes from the original PCH but the identifier comes from a
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // chained PCH, by storing the offset into the original PCH rather than
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // writing the macro definition a second time.
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (MI->isBuiltinMacro() ||
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        (Chain &&
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Name->isFromAST() && !Name->hasChangedSinceDeserialization() &&
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         MI->isFromAST() && !MI->hasChangedAfterLoad()))
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddIdentifierRef(Name, Record);
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MacroOffsets[Name] = Stream.GetCurrentBitNo();
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(MI->getDefinitionLoc().getRawEncoding());
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(MI->isUsed());
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(MI->isPublic());
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(MI->getVisibilityLocation(), Record);
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned Code;
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (MI->isObjectLike()) {
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Code = PP_MACRO_OBJECT_LIKE;
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Code = PP_MACRO_FUNCTION_LIKE;
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(MI->isC99Varargs());
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(MI->isGNUVarargs());
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(MI->getNumArgs());
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           I != E; ++I)
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        AddIdentifierRef(*I, Record);
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // If we have a detailed preprocessing record, record the macro definition
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // ID that corresponds to this macro.
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (PPRec)
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]);
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(Code, Record);
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the tokens array.
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Note that we know that the preprocessor does not have any annotation
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // tokens in it because they are created by the parser, and thus can't be
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // in a macro definition.
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const Token &Tok = MI->getReplacementToken(TokNo);
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Tok.getLocation().getRawEncoding());
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Tok.getLength());
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // FIXME: When reading literal tokens, reconstruct the literal pointer if
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // it is needed.
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddIdentifierRef(Tok.getIdentifierInfo(), Record);
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // FIXME: Should translate token kind to a stable encoding.
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Tok.getKind());
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // FIXME: Should translate token flags to a stable encoding.
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Tok.getFlags());
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecord(PP_TOKEN, Record);
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.clear();
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++NumMacros;
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (PPRec.local_begin() == PPRec.local_end())
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<PPEntityOffset, 64> PreprocessedEntityOffsets;
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Enter the preprocessor block.
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3);
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If the preprocessor has a preprocessing record, emit it.
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned NumPreprocessingRecords = 0;
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Set up the abbreviation for
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned InclusionAbbrev = 0;
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE));
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    InclusionAbbrev = Stream.EmitAbbrev(Abbrev);
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned FirstPreprocessorEntityID
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0)
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    + NUM_PREDEF_PP_ENTITY_IDS;
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (PreprocessingRecord::iterator E = PPRec.local_begin(),
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  EEnd = PPRec.local_end();
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       E != EEnd;
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    PreprocessedEntityOffsets.push_back(PPEntityOffset((*E)->getSourceRange(),
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                     Stream.GetCurrentBitNo()));
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Record this macro definition's ID.
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MacroDefinitions[MD] = NextPreprocessorEntityID;
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddIdentifierRef(MD->getName(), Record);
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecord(PPD_MACRO_DEFINITION, Record);
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*E)) {
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(ME->isBuiltinMacro());
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ME->isBuiltinMacro())
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        AddIdentifierRef(ME->getName(), Record);
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(MacroDefinitions[ME->getDefinition()]);
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecord(PPD_MACRO_EXPANSION, Record);
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(PPD_INCLUSION_DIRECTIVE);
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(ID->getFileName().size());
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(ID->wasInQuotes());
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(static_cast<unsigned>(ID->getKind()));
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SmallString<64> Buffer;
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Buffer += ID->getFileName();
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Check that the FileEntry is not null because it was not resolved and
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // we create a PCH even with compiler errors.
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ID->getFile())
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Buffer += ID->getFile()->getName();
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer);
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter");
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the offsets table for the preprocessing record.
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (NumPreprocessingRecords > 0) {
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(PreprocessedEntityOffsets.size() == NumPreprocessingRecords);
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Write the offsets table for identifier IDs.
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    using namespace llvm;
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(PPD_ENTITIES_OFFSETS));
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first pp entity
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(PPD_ENTITIES_OFFSETS);
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(FirstPreprocessorEntityID - NUM_PREDEF_PP_ENTITY_IDS);
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record,
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              data(PreprocessedEntityOffsets));
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned ASTWriter::getSubmoduleID(Module *Mod) {
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::DenseMap<Module *, unsigned>::iterator Known = SubmoduleIDs.find(Mod);
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Known != SubmoduleIDs.end())
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return Known->second;
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return SubmoduleIDs[Mod] = NextSubmoduleID++;
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Compute the number of modules within the given tree (including the
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// given module).
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned getNumberOfModules(Module *Mod) {
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned ChildModules = 0;
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (Module::submodule_iterator Sub = Mod->submodule_begin(),
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               SubEnd = Mod->submodule_end();
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       Sub != SubEnd; ++Sub)
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ChildModules += getNumberOfModules(*Sub);
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return ChildModules + 1;
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteSubmodules(Module *WritingModule) {
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Determine the dependencies of our module and each of it's submodules.
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: This feels like it belongs somewhere else, but there are no
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // other consumers of this information.
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SourceManager &SrcMgr = PP->getSourceManager();
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (ASTContext::import_iterator I = Context->local_import_begin(),
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                IEnd = Context->local_import_end();
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != IEnd; ++I) {
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Module *ImportedFrom
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          = ModMap.inferModuleFromLocation(FullSourceLoc(I->getLocation(),
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         SrcMgr))) {
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ImportedFrom->Imports.push_back(I->getImportedModule());
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Enter the submodule description block.
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the abbreviations needed for the submodules block.
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules...
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned DefinitionAbbrev = Stream.EmitAbbrev(Abbrev);
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev = new BitCodeAbbrev();
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_HEADER));
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned UmbrellaAbbrev = Stream.EmitAbbrev(Abbrev);
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev = new BitCodeAbbrev();
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER));
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned HeaderAbbrev = Stream.EmitAbbrev(Abbrev);
1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev = new BitCodeAbbrev();
1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_DIR));
1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(Abbrev);
1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev = new BitCodeAbbrev();
1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_REQUIRES));
1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Feature
1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned RequiresAbbrev = Stream.EmitAbbrev(Abbrev);
1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the submodule metadata block.
1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(getNumberOfModules(WritingModule));
1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS);
1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(SUBMODULE_METADATA, Record);
1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write all of the submodules.
1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::queue<Module *> Q;
1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Q.push(WritingModule);
1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (!Q.empty()) {
1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Module *Mod = Q.front();
1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Q.pop();
1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned ID = getSubmoduleID(Mod);
1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the definition of the block.
1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(SUBMODULE_DEFINITION);
1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(ID);
1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Mod->Parent) {
1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(SubmoduleIDs[Mod->Parent] && "Submodule parent not written?");
1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(SubmoduleIDs[Mod->Parent]);
1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(0);
1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Mod->IsFramework);
1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Mod->IsExplicit);
1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Mod->IsSystem);
1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Mod->InferSubmodules);
1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Mod->InferExplicitSubmodules);
1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Mod->InferExportWildcard);
1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the requirements.
1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0, N = Mod->Requires.size(); I != N; ++I) {
1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.clear();
1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(SUBMODULE_REQUIRES);
1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecordWithBlob(RequiresAbbrev, Record,
1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                Mod->Requires[I].data(),
1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                Mod->Requires[I].size());
1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the umbrella header, if there is one.
1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (const FileEntry *UmbrellaHeader = Mod->getUmbrellaHeader()) {
1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.clear();
1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(SUBMODULE_UMBRELLA_HEADER);
1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record,
1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                UmbrellaHeader->getName());
1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (const DirectoryEntry *UmbrellaDir = Mod->getUmbrellaDir()) {
1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.clear();
1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(SUBMODULE_UMBRELLA_DIR);
1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,
1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                UmbrellaDir->getName());
1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the headers.
1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0, N = Mod->Headers.size(); I != N; ++I) {
1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.clear();
2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(SUBMODULE_HEADER);
2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecordWithBlob(HeaderAbbrev, Record,
2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                Mod->Headers[I]->getName());
2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the imports.
2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!Mod->Imports.empty()) {
2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.clear();
2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned I = 0, N = Mod->Imports.size(); I != N; ++I) {
2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        unsigned ImportedID = getSubmoduleID(Mod->Imports[I]);
2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert(ImportedID && "Unknown submodule!");
2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(ImportedID);
2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the exports.
2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!Mod->Exports.empty()) {
2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.clear();
2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned I = 0, N = Mod->Exports.size(); I != N; ++I) {
2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (Module *Exported = Mod->Exports[I].getPointer()) {
2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          unsigned ExportedID = SubmoduleIDs[Exported];
2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          assert(ExportedID > 0 && "Unknown submodule ID?");
2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.push_back(ExportedID);
2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else {
2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          Record.push_back(0);
2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(Mod->Exports[I].getInt());
2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecord(SUBMODULE_EXPORTS, Record);
2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Queue up the submodules of this module.
2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (Module::submodule_iterator Sub = Mod->submodule_begin(),
2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 SubEnd = Mod->submodule_end();
2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Sub != SubEnd; ++Sub)
2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Q.push(*Sub);
2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert((NextSubmoduleID - FirstSubmoduleID
2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            == getNumberOfModules(WritingModule)) && "Wrong # of submodules");
2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgserialization::SubmoduleID
2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTWriter::inferSubmoduleIDFromLocation(SourceLocation Loc) {
2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Loc.isInvalid() || !WritingModule)
2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0; // No submodule
2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Find the module that owns this location.
2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Module *OwningMod
2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    = ModMap.inferModuleFromLocation(FullSourceLoc(Loc,PP->getSourceManager()));
2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!OwningMod)
2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Check whether this submodule is part of our own module.
2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (WritingModule != OwningMod && !OwningMod->isSubModuleOf(WritingModule))
2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return getSubmoduleID(OwningMod);
2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag) {
2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DiagnosticsEngine::DiagStatePointsTy::const_iterator
2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end();
2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I != E; ++I) {
2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const DiagnosticsEngine::DiagStatePoint &point = *I;
2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (point.Loc.isInvalid())
2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(point.Loc.getRawEncoding());
2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (DiagnosticsEngine::DiagState::const_iterator
2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           I = point.State->begin(), E = point.State->end(); I != E; ++I) {
2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (I->second.isPragma()) {
2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(I->first);
2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record.push_back(I->second.getMapping());
2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(-1); // mark the end of the diag/map pairs for this
2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          // location.
2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!Record.empty())
2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record);
2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteCXXBaseSpecifiersOffsets() {
2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (CXXBaseSpecifiersOffsets.empty())
2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create a blob abbreviation for the C++ base specifiers offsets.
2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS));
2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the base specifier offsets table.
2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(CXX_BASE_SPECIFIER_OFFSETS);
2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(CXXBaseSpecifiersOffsets.size());
2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record,
2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            data(CXXBaseSpecifiersOffsets));
2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Type Serialization
2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the representation of a type to the AST stream.
2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteType(QualType T) {
2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TypeIdx &Idx = TypeIdxs[T];
2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Idx.getIndex() == 0) // we haven't seen this type before.
2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Idx = TypeIdx(NextTypeID++);
2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST");
2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Record the offset for this type.
2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned Index = Idx.getIndex() - FirstTypeID;
2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (TypeOffsets.size() == Index)
2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    TypeOffsets.push_back(Stream.GetCurrentBitNo());
2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  else if (TypeOffsets.size() < Index) {
2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    TypeOffsets.resize(Index + 1);
2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    TypeOffsets[Index] = Stream.GetCurrentBitNo();
2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the type's representation.
2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTTypeWriter W(*this, Record);
2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (T.hasLocalNonFastQualifiers()) {
2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Qualifiers Qs = T.getLocalQualifiers();
2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTypeRef(T.getLocalUnqualifiedType(), Record);
2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Qs.getAsOpaqueValue());
2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    W.Code = TYPE_EXT_QUAL;
2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else {
2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (T->getTypeClass()) {
2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // For all of the concrete, non-dependent types, call the
2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // appropriate visitor function.
2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define TYPE(Class, Base) \
2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ABSTRACT_TYPE(Class, Base)
2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/TypeNodes.def"
2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the serialized record.
2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(W.Code, Record);
2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Flush any expressions that were written as part of this type.
2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FlushStmts();
2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Declaration Serialization
2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the block containing all of the declaration IDs
2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// lexically declared within the given DeclContext.
2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// bistream, or 0 if no block was written.
2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orguint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 DeclContext *DC) {
2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DC->decls_empty())
2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint64_t Offset = Stream.GetCurrentBitNo();
2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(DECL_CONTEXT_LEXICAL);
2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<KindDeclIDPair, 64> Decls;
2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         D != DEnd; ++D)
2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D)));
2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ++NumLexicalDeclContexts;
2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, data(Decls));
2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Offset;
2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteTypeDeclOffsets() {
2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the type offsets array
2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET));
2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base type index
2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TYPE_OFFSET);
2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TypeOffsets.size());
2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(FirstTypeID - NUM_PREDEF_TYPE_IDS);
2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, data(TypeOffsets));
2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the declaration offsets array
2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev = new BitCodeAbbrev();
2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET));
2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID
2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(DECL_OFFSET);
2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(DeclOffsets.size());
2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(FirstDeclID - NUM_PREDEF_DECL_IDS);
2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets));
2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteFileDeclIDsMap() {
2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Join the vectors of DeclIDs from all files.
2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<DeclID, 256> FileSortedIDs;
2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (FileDeclIDsTy::iterator
2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FI = FileDeclIDs.begin(), FE = FileDeclIDs.end(); FI != FE; ++FI) {
2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDInFileInfo &Info = *FI->second;
2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Info.FirstDeclIndex = FileSortedIDs.size();
2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (LocDeclIDsTy::iterator
2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           DI = Info.DeclIDs.begin(), DE = Info.DeclIDs.end(); DI != DE; ++DI)
2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FileSortedIDs.push_back(DI->second);
2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(FILE_SORTED_DECLS));
2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(FILE_SORTED_DECLS);
2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(AbbrevCode, Record, data(FileSortedIDs));
2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteComments() {
2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(COMMENTS_BLOCK_ID, 3);
2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ArrayRef<RawComment> RawComments = Context->Comments.getComments();
2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (ArrayRef<RawComment>::iterator I = RawComments.begin(),
2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      E = RawComments.end();
2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != E; ++I) {
2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceRange(I->getSourceRange(), Record);
2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I->getKind());
2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I->isTrailingComment());
2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I->isAlmostTrailingComment());
2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record);
2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Global Method Pool and Selector Serialization
2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Trait used for the on-disk hash table used in the method pool.
2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ASTMethodPoolTrait {
2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTWriter &Writer;
2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef Selector key_type;
2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef key_type key_type_ref;
2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct data_type {
2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SelectorID ID;
2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ObjCMethodList Instance, Factory;
2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  };
2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef const data_type& data_type_ref;
2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { }
2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static unsigned ComputeHash(Selector Sel) {
2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return serialization::ComputeHash(Sel);
2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::pair<unsigned,unsigned>
2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    EmitKeyDataLength(raw_ostream& Out, Selector Sel,
2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      data_type_ref Methods) {
2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, KeyLen);
2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts
2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (const ObjCMethodList *Method = &Methods.Instance; Method;
2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Method = Method->Next)
2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Method->Method)
2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        DataLen += 4;
2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (const ObjCMethodList *Method = &Methods.Factory; Method;
2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Method = Method->Next)
2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Method->Method)
2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        DataLen += 4;
2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, DataLen);
2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return std::make_pair(KeyLen, DataLen);
2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint64_t Start = Out.tell();
2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert((Start >> 32) == 0 && "Selector key offset too large");
2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.SetSelectorOffset(Sel, Start);
2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned N = Sel.getNumArgs();
2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, N);
2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (N == 0)
2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      N = 1;
2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0; I != N; ++I)
2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out,
2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitData(raw_ostream& Out, key_type_ref,
2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                data_type_ref Methods, unsigned DataLen) {
2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint64_t Start = Out.tell(); (void)Start;
2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit32(Out, Methods.ID);
2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned NumInstanceMethods = 0;
2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (const ObjCMethodList *Method = &Methods.Instance; Method;
2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Method = Method->Next)
2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Method->Method)
2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++NumInstanceMethods;
2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned NumFactoryMethods = 0;
2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (const ObjCMethodList *Method = &Methods.Factory; Method;
2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Method = Method->Next)
2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Method->Method)
2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++NumFactoryMethods;
2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, NumInstanceMethods);
2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, NumFactoryMethods);
2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (const ObjCMethodList *Method = &Methods.Instance; Method;
2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Method = Method->Next)
2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Method->Method)
2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (const ObjCMethodList *Method = &Methods.Factory; Method;
2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Method = Method->Next)
2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Method->Method)
2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(Out.tell() - Start == DataLen && "Data length is wrong");
2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // end anonymous namespace
2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write ObjC data: selectors and the method pool.
2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// The method pool contains both instance and factory methods, stored
2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// in an on-disk hash table indexed by the selector. The hash table also
2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// contains an empty entry for every other selector known to Sema.
2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteSelectors(Sema &SemaRef) {
2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Do we have to do anything at all?
2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (SemaRef.MethodPool.empty() && SelectorIDs.empty())
2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned NumTableEntries = 0;
2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create and write out the blob that contains selectors and the method pool.
2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator;
2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ASTMethodPoolTrait Trait(*this);
2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Create the on-disk hash table representation. We walk through every
2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // selector we've seen and look it up in the method pool.
2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SelectorOffsets.resize(NextSelectorID - FirstSelectorID);
2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (llvm::DenseMap<Selector, SelectorID>::iterator
2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             I = SelectorIDs.begin(), E = SelectorIDs.end();
2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I != E; ++I) {
2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Selector S = I->first;
2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S);
2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASTMethodPoolTrait::data_type Data = {
2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        I->second,
2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ObjCMethodList(),
2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ObjCMethodList()
2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      };
2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (F != SemaRef.MethodPool.end()) {
2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Data.Instance = F->second.first;
2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Data.Factory = F->second.second;
2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Only write this selector if it's not in an existing AST or something
2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // changed.
2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Chain && I->second < FirstSelectorID) {
2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // Selector already exists. Did it change?
2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        bool changed = false;
2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method;
2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             M = M->Next) {
2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          if (!M->Method->isFromASTFile())
2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            changed = true;
2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method;
2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             M = M->Next) {
2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          if (!M->Method->isFromASTFile())
2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            changed = true;
2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (!changed)
2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          continue;
2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (Data.Instance.Method || Data.Factory.Method) {
2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // A new method pool entry.
2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++NumTableEntries;
2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Generator.insert(S, Data, Trait);
2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Create the on-disk hash table in a buffer.
2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallString<4096> MethodPool;
2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint32_t BucketOffset;
2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASTMethodPoolTrait Trait(*this);
2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      llvm::raw_svector_ostream Out(MethodPool);
2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Make sure that no bucket is at offset 0
2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out, 0);
2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BucketOffset = Generator.Emit(Out, Trait);
2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Create a blob abbreviation
2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL));
2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev);
2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Write the method pool
2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    RecordData Record;
2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(METHOD_POOL);
2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(BucketOffset);
2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(NumTableEntries);
2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str());
2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Create a blob abbreviation for the selector table offsets.
2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev = new BitCodeAbbrev();
2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS));
2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Write the selector offsets table.
2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(SELECTOR_OFFSETS);
2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(SelectorOffsets.size());
2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(FirstSelectorID - NUM_PREDEF_SELECTOR_IDS);
2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              data(SelectorOffsets));
2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the selectors referenced in @selector expression into AST file.
2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (SemaRef.ReferencedSelectors.empty())
2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Note: this writes out all references even for a dependent AST. But it is
2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // very tricky to fix, and given that @selector shouldn't really appear in
2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // headers, probably not worth it. It's not a correctness issue.
2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DenseMap<Selector, SourceLocation>::iterator S =
2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       SemaRef.ReferencedSelectors.begin(),
2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       E = SemaRef.ReferencedSelectors.end(); S != E; ++S) {
2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Selector Sel = (*S).first;
2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SourceLocation Loc = (*S).second;
2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSelectorRef(Sel, Record);
2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(Loc, Record);
2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(REFERENCED_SELECTOR_POOL, Record);
2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Identifier Table Serialization
2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ASTIdentifierTableTrait {
2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTWriter &Writer;
2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Preprocessor &PP;
2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  IdentifierResolver &IdResolver;
2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool IsModule;
2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  /// \brief Determines whether this is an "interesting" identifier
2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  /// that needs a full IdentifierInfo structure written into the hash
2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  /// table.
2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool isInterestingIdentifier(IdentifierInfo *II, MacroInfo *&Macro) {
2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (II->isPoisoned() ||
2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        II->isExtensionToken() ||
2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        II->getObjCOrBuiltinID() ||
2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        II->hasRevertedTokenIDToIdentifier() ||
2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        II->getFETokenInfo<void>())
2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return hasMacroDefinition(II, Macro);
2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool hasMacroDefinition(IdentifierInfo *II, MacroInfo *&Macro) {
2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!II->hasMacroDefinition())
2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Macro || (Macro = PP.getMacroInfo(II)))
2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return !Macro->isBuiltinMacro() && (!IsModule || Macro->isPublic());
2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return false;
2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef IdentifierInfo* key_type;
2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef key_type  key_type_ref;
2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef IdentID data_type;
2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef data_type data_type_ref;
2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,
2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          IdentifierResolver &IdResolver, bool IsModule)
2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule) { }
2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static unsigned ComputeHash(const IdentifierInfo* II) {
2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return llvm::HashString(II->getName());
2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::pair<unsigned,unsigned>
2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned KeyLen = II->getLength() + 1;
2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MacroInfo *Macro = 0;
2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (isInterestingIdentifier(II, Macro)) {
2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DataLen += 2; // 2 bytes for builtin ID, flags
2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (hasMacroDefinition(II, Macro))
2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        DataLen += 8;
2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (IdentifierResolver::iterator D = IdResolver.begin(II),
2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     DEnd = IdResolver.end();
2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           D != DEnd; ++D)
2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        DataLen += sizeof(DeclID);
2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, DataLen);
2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // We emit the key length after the data length so that every
2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // string is preceded by a 16-bit length. This matches the PTH
2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // format for storing identifiers.
2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, KeyLen);
2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return std::make_pair(KeyLen, DataLen);
2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitKey(raw_ostream& Out, const IdentifierInfo* II,
2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               unsigned KeyLen) {
2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Record the location of the key data.  This is used when generating
2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // the mapping from persistent IDs to strings.
2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.SetIdentifierOffset(II, Out.tell());
2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Out.write(II->getNameStart(), KeyLen);
2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitData(raw_ostream& Out, IdentifierInfo* II,
2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                IdentID ID, unsigned) {
2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MacroInfo *Macro = 0;
2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!isInterestingIdentifier(II, Macro)) {
2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out, ID << 1);
2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit32(Out, (ID << 1) | 0x01);
2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint32_t Bits = 0;
2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bool HasMacroDefinition = hasMacroDefinition(II, Macro);
2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Bits = (uint32_t)II->getObjCOrBuiltinID();
2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert((Bits & 0x7ff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Bits = (Bits << 1) | unsigned(HasMacroDefinition);
2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Bits = (Bits << 1) | unsigned(II->isExtensionToken());
2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Bits = (Bits << 1) | unsigned(II->isPoisoned());
2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, Bits);
2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (HasMacroDefinition) {
2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out, Writer.getMacroOffset(II));
2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out,
2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Writer.inferSubmoduleIDFromLocation(Macro->getDefinitionLoc()));
2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Emit the declaration IDs in reverse order, because the
2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // IdentifierResolver provides the declarations as they would be
2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // visible (e.g., the function "stat" would come before the struct
2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // "stat"), but the ASTReader adds declarations to the end of the list
2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // (so we need to see the struct "status" before the function "status").
2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Only emit declarations that aren't from a chained PCH, though.
2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallVector<Decl *, 16> Decls(IdResolver.begin(II),
2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  IdResolver.end());
2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                DEnd = Decls.rend();
2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         D != DEnd; ++D)
2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out, Writer.getDeclID(*D));
2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // end anonymous namespace
2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the identifier table into the AST file.
2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// The identifier table consists of a blob containing string data
2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// (the actual identifiers themselves) and a separate "offsets" index
2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// that maps identifier IDs to locations within the blob.
2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteIdentifierTable(Preprocessor &PP,
2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     IdentifierResolver &IdResolver,
2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bool IsModule) {
2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create and write out the blob that contains the identifier
2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // strings.
2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule);
2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Look for any identifiers that were named while processing the
2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // headers, but are otherwise not needed. We add these to the hash
2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // table to enable checking of the predefines buffer in the case
2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // where the user adds new macro definitions when building the AST
2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // file.
2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),
2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                IDEnd = PP.getIdentifierTable().end();
2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ID != IDEnd; ++ID)
2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      getIdentifierRef(ID->second);
2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Create the on-disk hash table representation. We only store offsets
2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // for identifiers that appear here for the first time.
2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    IdentifierOffsets.resize(NextIdentID - FirstIdentID);
2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (llvm::DenseMap<const IdentifierInfo *, IdentID>::iterator
2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ID != IDEnd; ++ID) {
2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ID->first && "NULL identifier in identifier table");
2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!Chain || !ID->first->isFromAST() ||
2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ID->first->hasChangedSinceDeserialization())
2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Generator.insert(const_cast<IdentifierInfo *>(ID->first), ID->second,
2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         Trait);
2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Create the on-disk hash table in a buffer.
2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallString<4096> IdentifierTable;
2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint32_t BucketOffset;
2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule);
2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      llvm::raw_svector_ostream Out(IdentifierTable);
2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Make sure that no bucket is at offset 0
2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out, 0);
2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BucketOffset = Generator.Emit(Out, Trait);
2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Create a blob abbreviation
2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE));
2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev);
2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Write the identifier table
2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    RecordData Record;
2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(IDENTIFIER_TABLE);
2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(BucketOffset);
2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str());
2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the offsets table for identifier IDs.
2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET));
2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(IDENTIFIER_OFFSET);
2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(IdentifierOffsets.size());
2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(FirstIdentID - NUM_PREDEF_IDENT_IDS);
2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            data(IdentifierOffsets));
2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// DeclContext's Name Lookup Table Serialization
2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Trait used for the on-disk hash table used in the method pool.
2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ASTDeclContextNameLookupTrait {
2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTWriter &Writer;
2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef DeclarationName key_type;
2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef key_type key_type_ref;
2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef DeclContext::lookup_result data_type;
2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef const data_type& data_type_ref;
2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned ComputeHash(DeclarationName Name) {
2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::FoldingSetNodeID ID;
2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ID.AddInteger(Name.getNameKind());
2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (Name.getNameKind()) {
2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::Identifier:
2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ID.AddString(Name.getAsIdentifierInfo()->getName());
2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCZeroArgSelector:
2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCOneArgSelector:
2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCMultiArgSelector:
2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector()));
2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXConstructorName:
2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXDestructorName:
2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXConversionFunctionName:
2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXOperatorName:
2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ID.AddInteger(Name.getCXXOverloadedOperator());
2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXLiteralOperatorName:
2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ID.AddString(Name.getCXXLiteralIdentifier()->getName());
2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXUsingDirective:
2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ID.ComputeHash();
2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::pair<unsigned,unsigned>
2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    EmitKeyDataLength(raw_ostream& Out, DeclarationName Name,
2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      data_type_ref Lookup) {
2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned KeyLen = 1;
2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (Name.getNameKind()) {
2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::Identifier:
2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCZeroArgSelector:
2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCOneArgSelector:
2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCMultiArgSelector:
2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXLiteralOperatorName:
2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      KeyLen += 4;
2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXOperatorName:
2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      KeyLen += 1;
2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXConstructorName:
2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXDestructorName:
2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXConversionFunctionName:
2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXUsingDirective:
2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, KeyLen);
2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // 2 bytes for num of decls and 4 for each DeclID.
2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first);
2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, DataLen);
2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return std::make_pair(KeyLen, DataLen);
2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitKey(raw_ostream& Out, DeclarationName Name, unsigned) {
2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    using namespace clang::io;
2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(Name.getNameKind() < 0x100 && "Invalid name kind ?");
2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Emit8(Out, Name.getNameKind());
2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (Name.getNameKind()) {
2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::Identifier:
2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo()));
2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCZeroArgSelector:
2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCOneArgSelector:
2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::ObjCMultiArgSelector:
2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector()));
2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXOperatorName:
2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?");
2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Emit8(Out, Name.getCXXOverloadedOperator());
2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXLiteralOperatorName:
2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier()));
2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXConstructorName:
2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXDestructorName:
2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXConversionFunctionName:
2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case DeclarationName::CXXUsingDirective:
2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void EmitData(raw_ostream& Out, key_type_ref,
2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                data_type Lookup, unsigned DataLen) {
2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint64_t Start = Out.tell(); (void)Start;
2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit16(Out, Lookup.second - Lookup.first);
2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (; Lookup.first != Lookup.second; ++Lookup.first)
2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first));
2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(Out.tell() - Start == DataLen && "Data length is wrong");
2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // end anonymous namespace
2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write the block containing all of the declaration IDs
2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// visible from the given DeclContext.
2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// bitstream, or 0 if no block was written.
2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orguint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 DeclContext *DC) {
2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DC->getPrimaryContext() != DC)
2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Since there is no name lookup into functions or methods, don't bother to
2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // build a visible-declarations table for these entities.
2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DC->isFunctionOrMethod())
2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If not in C++, we perform name lookup for the translation unit via the
2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // IdentifierInfo chains, don't bother to build a visible-declarations table.
2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: In C++ we need the visible declarations in order to "see" the
2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // friend declarations, is there a way to do this without writing the table ?
2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DC->isTranslationUnit() && !Context.getLangOpts().CPlusPlus)
2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Serialize the contents of the mapping used for lookup. Note that,
2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // although we have two very different code paths, the serialized
2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // representation is the same for both cases: a declaration name,
2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // followed by a size, followed by references to the visible
2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // declarations that have that name.
2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint64_t Offset = Stream.GetCurrentBitNo();
2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  StoredDeclsMap *Map = DC->buildLookup();
2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!Map || Map->empty())
2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTDeclContextNameLookupTrait Trait(*this);
2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create the on-disk hash table representation.
2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DeclarationName ConversionName;
2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::SmallVector<NamedDecl *, 4> ConversionDecls;
2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       D != DEnd; ++D) {
2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclarationName Name = D->first;
2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclContext::lookup_result Result = D->second.getLookupResult();
2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Result.first != Result.second) {
2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // Hash all conversion function names to the same name. The actual
2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // type information in conversion function name is not used in the
2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // key (since such type information is not stable across different
2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // modules), so the intended effect is to coalesce all of the conversion
2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // functions under a single key.
2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (!ConversionName)
2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ConversionName = Name;
2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ConversionDecls.append(Result.first, Result.second);
2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        continue;
2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Generator.insert(Name, Result, Trait);
2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Add the conversion functions
2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!ConversionDecls.empty()) {
2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Generator.insert(ConversionName,
2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     DeclContext::lookup_result(ConversionDecls.begin(),
2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                ConversionDecls.end()),
2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     Trait);
2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create the on-disk hash table in a buffer.
2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallString<4096> LookupTable;
2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint32_t BucketOffset;
2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::raw_svector_ostream Out(LookupTable);
2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Make sure that no bucket is at offset 0
2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit32(Out, 0);
2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BucketOffset = Generator.Emit(Out, Trait);
2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the lookup table
2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(DECL_CONTEXT_VISIBLE);
2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(BucketOffset);
2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            LookupTable.str());
2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ++NumVisibleDeclContexts;
2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Offset;
2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write an UPDATE_VISIBLE block for the given context.
2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing
2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// DeclContext in a dependent AST file. As such, they only exist for the TU
2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// (in C++), for namespaces, and for classes with forward-declared unscoped
2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// enumeration members (in C++11).
2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!Map || Map->empty())
2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTDeclContextNameLookupTrait Trait(*this);
2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create the hash table.
2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       D != DEnd; ++D) {
2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclarationName Name = D->first;
2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclContext::lookup_result Result = D->second.getLookupResult();
2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // For any name that appears in this table, the results are complete, i.e.
2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // they overwrite results from previous PCHs. Merging is always a mess.
2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Result.first != Result.second)
2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Generator.insert(Name, Result, Trait);
2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create the on-disk hash table in a buffer.
2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallString<4096> LookupTable;
2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint32_t BucketOffset;
2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::raw_svector_ostream Out(LookupTable);
2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Make sure that no bucket is at offset 0
2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    clang::io::Emit32(Out, 0);
2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BucketOffset = Generator.Emit(Out, Trait);
2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the lookup table
2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(UPDATE_VISIBLE);
2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(getDeclID(cast<Decl>(DC)));
2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(BucketOffset);
2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str());
2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) {
2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Opts.fp_contract);
2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record);
2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write an OPENCL_EXTENSIONS block for the given OpenCLOptions.
2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) {
2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!SemaRef.Context.getLangOpts().OpenCL)
2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const OpenCLOptions &Opts = SemaRef.getOpenCLOptions();
2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define OPENCLEXT(nm)  Record.push_back(Opts.nm);
2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/OpenCLExtensions.def"
2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(OPENCL_EXTENSIONS, Record);
2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteRedeclarations() {
2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData LocalRedeclChains;
2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<serialization::LocalRedeclarationsInfo, 2> LocalRedeclsMap;
2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, N = Redeclarations.size(); I != N; ++I) {
2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Decl *First = Redeclarations[I];
2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(First->getPreviousDecl() == 0 && "Not the first declaration?");
2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Decl *MostRecent = First->getMostRecentDecl();
2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // If we only have a single declaration, there is no point in storing
2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // a redeclaration chain.
2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (First == MostRecent)
2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned Offset = LocalRedeclChains.size();
2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned Size = 0;
2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LocalRedeclChains.push_back(0); // Placeholder for the size.
2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Collect the set of local redeclarations of this declaration.
2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (Decl *Prev = MostRecent; Prev != First;
2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Prev = Prev->getPreviousDecl()) {
2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!Prev->isFromASTFile()) {
2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        AddDeclRef(Prev, LocalRedeclChains);
2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++Size;
2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LocalRedeclChains[Offset] = Size;
2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Reverse the set of local redeclarations, so that we store them in
2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // order (since we found them in reverse order).
2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    std::reverse(LocalRedeclChains.end() - Size, LocalRedeclChains.end());
2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Add the mapping from the first ID to the set of local declarations.
2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LocalRedeclarationsInfo Info = { getDeclID(First), Offset };
2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LocalRedeclsMap.push_back(Info);
2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(N == Redeclarations.size() &&
2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           "Deserialized a declaration we shouldn't have");
2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (LocalRedeclChains.empty())
2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Sort the local redeclarations map by the first declaration ID,
2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // since the reader will be performing binary searches on this information.
2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::array_pod_sort(LocalRedeclsMap.begin(), LocalRedeclsMap.end());
2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the local redeclarations map.
2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(LOCAL_REDECLARATIONS_MAP));
2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries
2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned AbbrevID = Stream.EmitAbbrev(Abbrev);
2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(LOCAL_REDECLARATIONS_MAP);
3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(LocalRedeclsMap.size());
3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(AbbrevID, Record,
3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    reinterpret_cast<char*>(LocalRedeclsMap.data()),
3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LocalRedeclsMap.size() * sizeof(LocalRedeclarationsInfo));
3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the redeclaration chains.
3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(LOCAL_REDECLARATIONS, LocalRedeclChains);
3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteObjCCategories() {
3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::SmallVector<ObjCCategoriesInfo, 2> CategoriesMap;
3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Categories;
3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) {
3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned Size = 0;
3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned StartIndex = Categories.size();
3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ObjCInterfaceDecl *Class = ObjCClassesWithCategories[I];
3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Allocate space for the size.
3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Categories.push_back(0);
3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Add the categories.
3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (ObjCCategoryDecl *Cat = Class->getCategoryList();
3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Cat; Cat = Cat->getNextClassCategory(), ++Size) {
3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(getDeclID(Cat) != 0 && "Bogus category");
3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(Cat, Categories);
3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Update the size.
3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Categories[StartIndex] = Size;
3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Record this interface -> category map.
3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ObjCCategoriesInfo CatInfo = { getDeclID(Class), StartIndex };
3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CategoriesMap.push_back(CatInfo);
3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Sort the categories map by the definition ID, since the reader will be
3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // performing binary searches on this information.
3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::array_pod_sort(CategoriesMap.begin(), CategoriesMap.end());
3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the categories map.
3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(OBJC_CATEGORIES_MAP));
3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries
3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned AbbrevID = Stream.EmitAbbrev(Abbrev);
3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(OBJC_CATEGORIES_MAP);
3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(CategoriesMap.size());
3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(AbbrevID, Record,
3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            reinterpret_cast<char*>(CategoriesMap.data()),
3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            CategoriesMap.size() * sizeof(ObjCCategoriesInfo));
3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the category lists.
3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(OBJC_CATEGORIES, Categories);
3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteMergedDecls() {
3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!Chain || Chain->MergedDecls.empty())
3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (ASTReader::MergedDeclsMap::iterator I = Chain->MergedDecls.begin(),
3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        IEnd = Chain->MergedDecls.end();
3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != IEnd; ++I) {
3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclID CanonID = I->first->isFromASTFile()? I->first->getGlobalID()
3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              : getDeclID(I->first);
3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(CanonID && "Merged declaration not known?");
3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(CanonID);
3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I->second.size());
3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.append(I->second.begin(), I->second.end());
3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(MERGED_DECLARATIONS, Record);
3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// General Serialization Routines
3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Write a record containing the given attributes.
3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) {
3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Attrs.size());
3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){
3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const Attr * A = *i;
3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs
3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceRange(A->getRange(), Record);
3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Serialization/AttrPCHWrite.inc"
3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) {
3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Str.size());
3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.insert(Record.end(), Str.begin(), Str.end());
3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddVersionTuple(const VersionTuple &Version,
3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                RecordDataImpl &Record) {
3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Version.getMajor());
3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (llvm::Optional<unsigned> Minor = Version.getMinor())
3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(*Minor + 1);
3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  else
3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(0);
3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (llvm::Optional<unsigned> Subminor = Version.getSubminor())
3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(*Subminor + 1);
3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  else
3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(0);
3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Note that the identifier II occurs at the given offset
3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// within the identifier table.
3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  IdentID ID = IdentifierIDs[II];
3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Only store offsets new to this AST file. Other identifier names are looked
3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // up earlier in the chain and thus don't need an offset.
3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (ID >= FirstIdentID)
3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    IdentifierOffsets[ID - FirstIdentID] = Offset;
3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Note that the selector Sel occurs at the given offset
3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// within the method pool/selector table.
3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned ID = SelectorIDs[Sel];
3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(ID && "Unknown selector");
3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Don't record offsets for selectors that are also available in a different
3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // file.
3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (ID < FirstSelectorID)
3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SelectorOffsets[ID - FirstSelectorID] = Offset;
3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  : Stream(Stream), Context(0), PP(0), Chain(0), WritingModule(0),
3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    WritingAST(false), ASTHasCompilerErrors(false),
3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),
3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NextSubmoduleID(FirstSubmoduleID),
3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CollectedStmts(&StmtsToEmit),
3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NumVisibleDeclContexts(0),
3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NextCXXBaseSpecifiersID(1),
3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0),
3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0),
3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0),
3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclRecordAbbrev(0), IntegerLiteralAbbrev(0),
3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclTypedefAbbrev(0),
3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclVarAbbrev(0), DeclFieldAbbrev(0),
3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclEnumAbbrev(0), DeclObjCIvarAbbrev(0)
3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTWriter::~ASTWriter() {
3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (FileDeclIDsTy::iterator
3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I = FileDeclIDs.begin(), E = FileDeclIDs.end(); I != E; ++I)
3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    delete I->second;
3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const std::string &OutputFile,
3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         Module *WritingModule, StringRef isysroot,
3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         bool hasErrors) {
3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WritingAST = true;
3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTHasCompilerErrors = hasErrors;
3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Emit the file header.
3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.Emit((unsigned)'C', 8);
3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.Emit((unsigned)'P', 8);
3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.Emit((unsigned)'C', 8);
3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.Emit((unsigned)'H', 8);
3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteBlockInfoBlock();
3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Context = &SemaRef.Context;
3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  PP = &SemaRef.PP;
3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  this->WritingModule = WritingModule;
3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile, WritingModule);
3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Context = 0;
3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  PP = 0;
3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  this->WritingModule = 0;
3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WritingAST = false;
3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<typename Vector>
3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               ASTWriter::RecordData &Record) {
3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename Vector::iterator I = Vec.begin(0, true), E = Vec.end();
3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != E; ++I)  {
3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Writer.AddDeclRef(*I, Record);
3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             StringRef isysroot,
3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const std::string &OutputFile,
3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             Module *WritingModule) {
3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  using namespace llvm;
3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Make sure that the AST reader knows to finalize itself.
3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Chain)
3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Chain->finalizeForWriting();
3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASTContext &Context = SemaRef.Context;
3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Preprocessor &PP = SemaRef.PP;
3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Set up predefined declaration IDs.
3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DeclIDs[Context.getTranslationUnitDecl()] = PREDEF_DECL_TRANSLATION_UNIT_ID;
3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.ObjCIdDecl)
3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.ObjCIdDecl] = PREDEF_DECL_OBJC_ID_ID;
3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.ObjCSelDecl)
3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.ObjCSelDecl] = PREDEF_DECL_OBJC_SEL_ID;
3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.ObjCClassDecl)
3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.ObjCClassDecl] = PREDEF_DECL_OBJC_CLASS_ID;
3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.ObjCProtocolClassDecl)
3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.ObjCProtocolClassDecl] = PREDEF_DECL_OBJC_PROTOCOL_ID;
3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.Int128Decl)
3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.Int128Decl] = PREDEF_DECL_INT_128_ID;
3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.UInt128Decl)
3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.UInt128Decl] = PREDEF_DECL_UNSIGNED_INT_128_ID;
3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.ObjCInstanceTypeDecl)
3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.ObjCInstanceTypeDecl] = PREDEF_DECL_OBJC_INSTANCETYPE_ID;
3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.BuiltinVaListDecl)
3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclIDs[Context.getBuiltinVaListDecl()] = PREDEF_DECL_BUILTIN_VA_LIST_ID;
3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!Chain) {
3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Make sure that we emit IdentifierInfos (and any attached
3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // declarations) for builtins. We don't need to do this when we're
3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // emitting chained PCH files, because all of the builtins will be
3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // in the original PCH file.
3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // FIXME: Modules won't like this at all.
3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    IdentifierTable &Table = PP.getIdentifierTable();
3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallVector<const char *, 32> BuiltinNames;
3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Context.BuiltinInfo.GetBuiltinNames(BuiltinNames,
3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        Context.getLangOpts().NoBuiltin);
3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I)
3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      getIdentifierRef(&Table.get(BuiltinNames[I]));
3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If there are any out-of-date identifiers, bring them up to date.
3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (ExternalPreprocessorSource *ExtSource = PP.getExternalSource()) {
3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),
3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                IDEnd = PP.getIdentifierTable().end();
3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ID != IDEnd; ++ID)
3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ID->second->isOutOfDate())
3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ExtSource->updateOutOfDateIdentifier(*ID->second);
3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of the tentative definitions in this file, in
3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // TentativeDefinitions order.  Generally, this record will be empty for
3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // headers.
3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData TentativeDefinitions;
3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions);
3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of the file scoped decls in this file.
3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData UnusedFileScopedDecls;
3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls,
3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     UnusedFileScopedDecls);
3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of the delegating constructors we still need
3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // to resolve.
3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData DelegatingCtorDecls;
3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddLazyVectorDecls(*this, SemaRef.DelegatingCtorDecls, DelegatingCtorDecls);
3273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the set of weak, undeclared identifiers. We always write the
3275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // entire table, since later PCH files in a PCH chain are only interested in
3276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // the results at the end of the chain.
3277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData WeakUndeclaredIdentifiers;
3278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!SemaRef.WeakUndeclaredIdentifiers.empty()) {
3279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator
3280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I = SemaRef.WeakUndeclaredIdentifiers.begin(),
3281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) {
3282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddIdentifierRef(I->first, WeakUndeclaredIdentifiers);
3283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers);
3284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers);
3285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      WeakUndeclaredIdentifiers.push_back(I->second.getUsed());
3286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of the locally-scoped external
3290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // declarations in this header file. Generally, this record will be
3291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // empty.
3292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData LocallyScopedExternalDecls;
3293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: This is filling in the AST file in densemap order which is
3294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // nondeterminstic!
3295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
3296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         TD = SemaRef.LocallyScopedExternalDecls.begin(),
3297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         TDEnd = SemaRef.LocallyScopedExternalDecls.end();
3298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       TD != TDEnd; ++TD) {
3299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!TD->second->isFromASTFile())
3300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(TD->second, LocallyScopedExternalDecls);
3301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of the ext_vector declarations.
3304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData ExtVectorDecls;
3305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls);
3306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of the VTable uses information.
3308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData VTableUses;
3309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!SemaRef.VTableUses.empty()) {
3310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
3311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(SemaRef.VTableUses[I].first, VTableUses);
3312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
3313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]);
3314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of dynamic classes declarations.
3318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData DynamicClasses;
3319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses);
3320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of pending implicit instantiations.
3322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData PendingInstantiations;
3323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (std::deque<Sema::PendingImplicitInstantiation>::iterator
3324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I = SemaRef.PendingInstantiations.begin(),
3325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         N = SemaRef.PendingInstantiations.end(); I != N; ++I) {
3326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(I->first, PendingInstantiations);
3327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(I->second, PendingInstantiations);
3328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
3330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "There are local ones at end of translation unit!");
3331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing some declaration references.
3333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData SemaDeclRefs;
3334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) {
3335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs);
3336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs);
3337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData CUDASpecialDeclRefs;
3340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Context.getcudaConfigureCallDecl()) {
3341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(Context.getcudaConfigureCallDecl(), CUDASpecialDeclRefs);
3342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Build a record containing all of the known namespaces.
3345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData KnownNamespaces;
3346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (llvm::DenseMap<NamespaceDecl*, bool>::iterator
3347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            I = SemaRef.KnownNamespaces.begin(),
3348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         IEnd = SemaRef.KnownNamespaces.end();
3349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != IEnd; ++I) {
3350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!I->second)
3351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(I->first, KnownNamespaces);
3352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the remaining AST contents.
3355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
3356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(AST_BLOCK_ID, 5);
3357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteMetadata(Context, isysroot, OutputFile);
3358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteLanguageOptions(Context.getLangOpts());
3359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (StatCalls && isysroot.empty())
3360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    WriteStatCache(*StatCalls);
3361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Create a lexical update block containing all of the declarations in the
3363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // translation unit that do not come from other AST files.
3364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<KindDeclIDPair, 64> NewGlobalDecls;
3366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DeclContext::decl_iterator I = TU->noload_decls_begin(),
3367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  E = TU->noload_decls_end();
3368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != E; ++I) {
3369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!(*I)->isFromASTFile())
3370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      NewGlobalDecls.push_back(std::make_pair((*I)->getKind(), GetDeclRef(*I)));
3371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
3374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
3375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
3376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abv);
3377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
3378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TU_UPDATE_LEXICAL);
3379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
3380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            data(NewGlobalDecls));
3381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // And a visible updates block for the translation unit.
3383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abv = new llvm::BitCodeAbbrev();
3384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
3385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
3386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32));
3387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
3388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv);
3389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteDeclContextVisibleUpdate(TU);
3390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If the translation unit has an anonymous namespace, and we don't already
3392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // have an update block for it, write it as an update block.
3393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
3394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
3395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Record.empty()) {
3396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
3397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(reinterpret_cast<uint64_t>(NS));
3398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Resolve any declaration pointers within the declaration updates block.
3402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ResolveDeclUpdatesBlocks();
3403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Form the record of special types.
3405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData SpecialTypes;
3406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes);
3407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.getFILEType(), SpecialTypes);
3408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.getjmp_bufType(), SpecialTypes);
3409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.getsigjmp_bufType(), SpecialTypes);
3410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.ObjCIdRedefinitionType, SpecialTypes);
3411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.ObjCClassRedefinitionType, SpecialTypes);
3412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes);
3413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(Context.getucontext_tType(), SpecialTypes);
3414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Keep writing types and declarations until all types and
3416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // declarations have been written.
3417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
3418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteDeclsBlockAbbrevs();
3419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DeclsToRewriteTy::iterator I = DeclsToRewrite.begin(),
3420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  E = DeclsToRewrite.end();
3421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != E; ++I)
3422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclTypesToEmit.push(const_cast<Decl*>(*I));
3423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (!DeclTypesToEmit.empty()) {
3424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclOrType DOT = DeclTypesToEmit.front();
3425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclTypesToEmit.pop();
3426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DOT.isType())
3427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      WriteType(DOT.getType());
3428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    else
3429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      WriteDecl(Context, DOT.getDecl());
3430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
3432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteFileDeclIDsMap();
3434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
3435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteComments();
3436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Chain) {
3438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Write the mapping information describing our module dependencies and how
3439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // each of those modules were mapped into our own offset/ID space, so that
3440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // the reader can build the appropriate mapping to its own offset/ID space.
3441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // The map consists solely of a blob with the following format:
3442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // *(module-name-len:i16 module-name:len*i8
3443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   source-location-offset:i32
3444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   identifier-id:i32
3445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   preprocessed-entity-id:i32
3446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   macro-definition-id:i32
3447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   submodule-id:i32
3448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   selector-id:i32
3449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   declaration-id:i32
3450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   c++-base-specifiers-id:i32
3451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //   type-id:i32)
3452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //
3453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    llvm::BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
3454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
3455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(Abbrev);
3457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SmallString<2048> Buffer;
3458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
3459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      llvm::raw_svector_ostream Out(Buffer);
3460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (ModuleManager::ModuleConstIterator M = Chain->ModuleMgr.begin(),
3461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           MEnd = Chain->ModuleMgr.end();
3462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           M != MEnd; ++M) {
3463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        StringRef FileName = (*M)->FileName;
3464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit16(Out, FileName.size());
3465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Out.write(FileName.data(), FileName.size());
3466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit32(Out, (*M)->SLocEntryBaseOffset);
3467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit32(Out, (*M)->BaseIdentifierID);
3468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit32(Out, (*M)->BasePreprocessedEntityID);
3469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit32(Out, (*M)->BaseSubmoduleID);
3470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit32(Out, (*M)->BaseSelectorID);
3471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit32(Out, (*M)->BaseDeclID);
3472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        io::Emit32(Out, (*M)->BaseTypeIndex);
3473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
3476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(MODULE_OFFSET_MAP);
3477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
3478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              Buffer.data(), Buffer.size());
3479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WritePreprocessor(PP, WritingModule != 0);
3481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot);
3482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteSelectors(SemaRef);
3483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteReferencedSelectorsPool(SemaRef);
3484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteIdentifierTable(PP, SemaRef.IdResolver, WritingModule != 0);
3485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteFPPragmaOptions(SemaRef.getFPOptions());
3486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteOpenCLExtensions(SemaRef);
3487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteTypeDeclOffsets();
3489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WritePragmaDiagnosticMappings(Context.getDiagnostics());
3490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteCXXBaseSpecifiersOffsets();
3492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If we're emitting a module, write out the submodule information.
3494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (WritingModule)
3495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    WriteSubmodules(WritingModule);
3496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
3498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing external, unnamed definitions.
3500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!ExternalDefinitions.empty())
3501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions);
3502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing tentative definitions.
3504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!TentativeDefinitions.empty())
3505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
3506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing unused file scoped decls.
3508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!UnusedFileScopedDecls.empty())
3509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
3510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing weak undeclared identifiers.
3512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!WeakUndeclaredIdentifiers.empty())
3513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
3514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      WeakUndeclaredIdentifiers);
3515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing locally-scoped external definitions.
3517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!LocallyScopedExternalDecls.empty())
3518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS,
3519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      LocallyScopedExternalDecls);
3520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing ext_vector type names.
3522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!ExtVectorDecls.empty())
3523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
3524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing VTable uses information.
3526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!VTableUses.empty())
3527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(VTABLE_USES, VTableUses);
3528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing dynamic classes declarations.
3530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!DynamicClasses.empty())
3531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses);
3532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing pending implicit instantiations.
3534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!PendingInstantiations.empty())
3535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
3536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing declaration references of Sema.
3538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!SemaDeclRefs.empty())
3539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
3540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the record containing CUDA-specific declaration references.
3542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!CUDASpecialDeclRefs.empty())
3543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs);
3544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the delegating constructors.
3546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!DelegatingCtorDecls.empty())
3547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
3548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the known namespaces.
3550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!KnownNamespaces.empty())
3551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
3552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Write the visible updates to DeclContexts.
3554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator
3555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I = UpdatedDeclContexts.begin(),
3556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       E = UpdatedDeclContexts.end();
3557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I != E; ++I)
3558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    WriteDeclContextVisibleUpdate(*I);
3559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!WritingModule) {
3561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Write the submodules that were imported, if any.
3562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    RecordData ImportedModules;
3563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (ASTContext::import_iterator I = Context.local_import_begin(),
3564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  IEnd = Context.local_import_end();
3565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I != IEnd; ++I) {
3566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(SubmoduleIDs.find(I->getImportedModule()) != SubmoduleIDs.end());
3567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ImportedModules.push_back(SubmoduleIDs[I->getImportedModule()]);
3568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!ImportedModules.empty()) {
3570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Sort module IDs.
3571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      llvm::array_pod_sort(ImportedModules.begin(), ImportedModules.end());
3572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Unique module IDs.
3574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ImportedModules.erase(std::unique(ImportedModules.begin(),
3575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        ImportedModules.end()),
3576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            ImportedModules.end());
3577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Stream.EmitRecord(IMPORTED_MODULES, ImportedModules);
3579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteDeclUpdatesBlocks();
3583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteDeclReplacementsBlock();
3584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteMergedDecls();
3585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteRedeclarations();
3586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  WriteObjCCategories();
3587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Some simple statistics
3589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.clear();
3590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NumStatements);
3591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NumMacros);
3592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NumLexicalDeclContexts);
3593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NumVisibleDeclContexts);
3594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(STATISTICS, Record);
3595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
3596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Go through the declaration update blocks and resolve declaration
3599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// pointers into declaration IDs.
3600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::ResolveDeclUpdatesBlocks() {
3601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DeclUpdateMap::iterator
3602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) {
3603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const Decl *D = I->first;
3604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    UpdateRecord &URec = I->second;
3605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (isRewritten(D))
3607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue; // The decl will be written completely
3608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned Idx = 0, N = URec.size();
3610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    while (Idx < N) {
3611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch ((DeclUpdateKind)URec[Idx++]) {
3612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UPD_CXX_ADDED_IMPLICIT_MEMBER:
3613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
3614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
3615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
3616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++Idx;
3617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        break;
3618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
3620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++Idx;
3621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        break;
3622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteDeclUpdatesBlocks() {
3628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DeclUpdates.empty())
3629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData OffsetsRecord;
3632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
3633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (DeclUpdateMap::iterator
3634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) {
3635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const Decl *D = I->first;
3636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    UpdateRecord &URec = I->second;
3637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (isRewritten(D))
3639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue; // The decl will be written completely,no need to store updates.
3640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint64_t Offset = Stream.GetCurrentBitNo();
3642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(DECL_UPDATES, URec);
3643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    OffsetsRecord.push_back(GetDeclRef(D));
3645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    OffsetsRecord.push_back(Offset);
3646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.ExitBlock();
3648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(DECL_UPDATE_OFFSETS, OffsetsRecord);
3649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::WriteDeclReplacementsBlock() {
3652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (ReplacedDecls.empty())
3653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
3656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (SmallVector<ReplacedDeclInfo, 16>::iterator
3657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) {
3658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I->ID);
3659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I->Offset);
3660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I->Loc);
3661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Stream.EmitRecord(DECL_REPLACEMENTS, Record);
3663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) {
3666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Loc.getRawEncoding());
3667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) {
3670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceLocation(Range.getBegin(), Record);
3671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceLocation(Range.getEnd(), Record);
3672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record) {
3675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Value.getBitWidth());
3676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const uint64_t *Words = Value.getRawData();
3677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.append(Words, Words + Value.getNumWords());
3678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record) {
3681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Value.isUnsigned());
3682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddAPInt(Value, Record);
3683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record) {
3686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddAPInt(Value.bitcastToAPInt(), Record);
3687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) {
3690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(getIdentifierRef(II));
3691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgIdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
3694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (II == 0)
3695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
3696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  IdentID &ID = IdentifierIDs[II];
3698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (ID == 0)
3699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ID = NextIdentID++;
3700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return ID;
3701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) {
3704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(getSelectorRef(SelRef));
3705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSelectorID ASTWriter::getSelectorRef(Selector Sel) {
3708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Sel.getAsOpaquePtr() == 0) {
3709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
3710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SelectorID &SID = SelectorIDs[Sel];
3713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (SID == 0 && Chain) {
3714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // This might trigger a ReadSelector callback, which will set the ID for
3715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // this selector.
3716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Chain->LoadSelector(Sel);
3717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (SID == 0) {
3719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SID = NextSelectorID++;
3720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return SID;
3722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record) {
3725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddDeclRef(Temp->getDestructor(), Record);
3726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
3729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      CXXBaseSpecifier const *BasesEnd,
3730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        RecordDataImpl &Record) {
3731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded");
3732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CXXBaseSpecifiersToWrite.push_back(
3733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                QueuedCXXBaseSpecifiers(NextCXXBaseSpecifiersID,
3734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                        Bases, BasesEnd));
3735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NextCXXBaseSpecifiersID++);
3736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
3739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           const TemplateArgumentLocInfo &Arg,
3740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           RecordDataImpl &Record) {
3741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (Kind) {
3742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Expression:
3743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddStmt(Arg.getAsExpr());
3744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Type:
3746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record);
3747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Template:
3749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record);
3750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(Arg.getTemplateNameLoc(), Record);
3751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::TemplateExpansion:
3753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record);
3754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(Arg.getTemplateNameLoc(), Record);
3755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record);
3756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Null:
3758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Integral:
3759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Declaration:
3760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Pack:
3761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
3766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       RecordDataImpl &Record) {
3767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTemplateArgument(Arg.getArgument(), Record);
3768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Arg.getArgument().getKind() == TemplateArgument::Expression) {
3770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bool InfoHasSameExpr
3771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
3772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(InfoHasSameExpr);
3773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (InfoHasSameExpr)
3774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; // Avoid storing the same expr twice.
3775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(),
3777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             Record);
3778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo,
3781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  RecordDataImpl &Record) {
3782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (TInfo == 0) {
3783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTypeRef(QualType(), Record);
3784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeLoc(TInfo->getTypeLoc(), Record);
3788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddTypeLoc(TypeLoc TL, RecordDataImpl &Record) {
3791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeRef(TL.getType(), Record);
3792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TypeLocWriter TLW(*this, Record);
3794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (; !TL.isNull(); TL = TL.getNextTypeLoc())
3795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    TLW.Visit(TL);
3796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) {
3799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(GetOrCreateTypeID(T));
3800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTypeID ASTWriter::GetOrCreateTypeID( QualType T) {
3803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return MakeTypeID(*Context, T,
3804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this));
3805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTypeID ASTWriter::getTypeID(QualType T) const {
3808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return MakeTypeID(*Context, T,
3809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this));
3810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) {
3813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (T.isNull())
3814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return TypeIdx();
3815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!T.getLocalFastQualifiers());
3816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TypeIdx &Idx = TypeIdxs[T];
3818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Idx.getIndex() == 0) {
3819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // We haven't seen this type before. Assign it a new ID and put it
3820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // into the queue of types to emit.
3821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Idx = TypeIdx(NextTypeID++);
3822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclTypesToEmit.push(T);
3823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Idx;
3825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTypeIdx ASTWriter::getTypeIdx(QualType T) const {
3828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (T.isNull())
3829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return TypeIdx();
3830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!T.getLocalFastQualifiers());
3831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TypeIdxMap::const_iterator I = TypeIdxs.find(T);
3833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(I != TypeIdxs.end() && "Type not emitted!");
3834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return I->second;
3835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
3838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(GetDeclRef(D));
3839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgDeclID ASTWriter::GetDeclRef(const Decl *D) {
3842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(WritingAST && "Cannot request a declaration ID before AST writing");
3843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (D == 0) {
3845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
3846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If D comes from an AST file, its declaration ID is already known and
3849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // fixed.
3850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (D->isFromASTFile())
3851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return D->getGlobalID();
3852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
3854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DeclID &ID = DeclIDs[D];
3855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (ID == 0) {
3856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // We haven't seen this declaration before. Give it a new ID and
3857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // enqueue it in the list of declarations to emit.
3858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ID = NextDeclID++;
3859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeclTypesToEmit.push(const_cast<Decl *>(D));
3860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return ID;
3863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgDeclID ASTWriter::getDeclID(const Decl *D) {
3866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (D == 0)
3867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
3868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If D comes from an AST file, its declaration ID is already known and
3870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // fixed.
3871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (D->isFromASTFile())
3872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return D->getGlobalID();
3873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!");
3875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return DeclIDs[D];
3876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline bool compLocDecl(std::pair<unsigned, serialization::DeclID> L,
3879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               std::pair<unsigned, serialization::DeclID> R) {
3880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return L.first < R.first;
3881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) {
3884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(ID);
3885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(D);
3886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SourceLocation Loc = D->getLocation();
3888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Loc.isInvalid())
3889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // We only keep track of the file-level declarations of each file.
3892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!D->getLexicalDeclContext()->isFileContext())
3893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: ParmVarDecls that are part of a function type of a parameter of
3895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // a function/objc method, should not have TU as lexical context.
3896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (isa<ParmVarDecl>(D))
3897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SourceManager &SM = Context->getSourceManager();
3900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SourceLocation FileLoc = SM.getFileLoc(Loc);
3901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(SM.isLocalSourceLocation(FileLoc));
3902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FileID FID;
3903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned Offset;
3904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  llvm::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
3905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (FID.isInvalid())
3906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const SrcMgr::SLocEntry *Entry = &SM.getSLocEntry(FID);
3908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(Entry->isFile());
3909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DeclIDInFileInfo *&Info = FileDeclIDs[Entry];
3911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!Info)
3912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Info = new DeclIDInFileInfo();
3913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::pair<unsigned, serialization::DeclID> LocDecl(Offset, ID);
3915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LocDeclIDsTy &Decls = Info->DeclIDs;
3916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Decls.empty() || Decls.back().first <= Offset) {
3918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Decls.push_back(LocDecl);
3919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
3920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LocDeclIDsTy::iterator
3923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    I = std::upper_bound(Decls.begin(), Decls.end(), LocDecl, compLocDecl);
3924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Decls.insert(I, LocDecl);
3926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddDeclarationName(DeclarationName Name, RecordDataImpl &Record) {
3929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: Emit a stable enum for NameKind.  0 = Identifier etc.
3930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Name.getNameKind());
3931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (Name.getNameKind()) {
3932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::Identifier:
3933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
3934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::ObjCZeroArgSelector:
3937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::ObjCOneArgSelector:
3938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::ObjCMultiArgSelector:
3939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSelectorRef(Name.getObjCSelector(), Record);
3940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXConstructorName:
3943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXDestructorName:
3944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXConversionFunctionName:
3945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTypeRef(Name.getCXXNameType(), Record);
3946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXOperatorName:
3949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Name.getCXXOverloadedOperator());
3950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXLiteralOperatorName:
3953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record);
3954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXUsingDirective:
3957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // No extra data to emit
3958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
3963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     DeclarationName Name, RecordDataImpl &Record) {
3964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (Name.getNameKind()) {
3965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXConstructorName:
3966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXDestructorName:
3967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXConversionFunctionName:
3968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTypeSourceInfo(DNLoc.NamedType.TInfo, Record);
3969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXOperatorName:
3972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(
3973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.BeginOpNameLoc),
3974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       Record);
3975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(
3976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc),
3977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Record);
3978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXLiteralOperatorName:
3981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(
3982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     SourceLocation::getFromRawEncoding(DNLoc.CXXLiteralOperatorName.OpNameLoc),
3983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     Record);
3984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::Identifier:
3987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::ObjCZeroArgSelector:
3988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::ObjCOneArgSelector:
3989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::ObjCMultiArgSelector:
3990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case DeclarationName::CXXUsingDirective:
3991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
3992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
3996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       RecordDataImpl &Record) {
3997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddDeclarationName(NameInfo.getName(), Record);
3998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceLocation(NameInfo.getLoc(), Record);
3999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName(), Record);
4000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddQualifierInfo(const QualifierInfo &Info,
4003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 RecordDataImpl &Record) {
4004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddNestedNameSpecifierLoc(Info.QualifierLoc, Record);
4005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Info.NumTemplParamLists);
4006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i)
4007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTemplateParameterList(Info.TemplParamLists[i], Record);
4008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
4011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       RecordDataImpl &Record) {
4012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Nested name specifiers usually aren't too long. I think that 8 would
4013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // typically accommodate the vast majority.
4014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<NestedNameSpecifier *, 8> NestedNames;
4015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Push each of the NNS's onto a stack for serialization in reverse order.
4017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (NNS) {
4018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NestedNames.push_back(NNS);
4019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NNS = NNS->getPrefix();
4020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NestedNames.size());
4023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while(!NestedNames.empty()) {
4024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NNS = NestedNames.pop_back_val();
4025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NestedNameSpecifier::SpecifierKind Kind = NNS->getKind();
4026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Kind);
4027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (Kind) {
4028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::Identifier:
4029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddIdentifierRef(NNS->getAsIdentifier(), Record);
4030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::Namespace:
4033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(NNS->getAsNamespace(), Record);
4034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::NamespaceAlias:
4037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(NNS->getAsNamespaceAlias(), Record);
4038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::TypeSpec:
4041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::TypeSpecWithTemplate:
4042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddTypeRef(QualType(NNS->getAsType(), 0), Record);
4043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
4044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::Global:
4047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Don't need to write an associated value.
4048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
4050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
4054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          RecordDataImpl &Record) {
4055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Nested name specifiers usually aren't too long. I think that 8 would
4056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // typically accommodate the vast majority.
4057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
4058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Push each of the nested-name-specifiers's onto a stack for
4060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // serialization in reverse order.
4061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (NNS) {
4062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NestedNames.push_back(NNS);
4063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NNS = NNS.getPrefix();
4064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NestedNames.size());
4067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while(!NestedNames.empty()) {
4068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NNS = NestedNames.pop_back_val();
4069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NestedNameSpecifier::SpecifierKind Kind
4070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = NNS.getNestedNameSpecifier()->getKind();
4071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Kind);
4072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (Kind) {
4073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::Identifier:
4074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier(), Record);
4075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceRange(NNS.getLocalSourceRange(), Record);
4076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::Namespace:
4079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace(), Record);
4080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceRange(NNS.getLocalSourceRange(), Record);
4081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::NamespaceAlias:
4084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), Record);
4085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceRange(NNS.getLocalSourceRange(), Record);
4086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::TypeSpec:
4089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::TypeSpecWithTemplate:
4090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
4091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddTypeLoc(NNS.getTypeLoc(), Record);
4092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
4093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case NestedNameSpecifier::Global:
4096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
4097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
4099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) {
4103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TemplateName::NameKind Kind = Name.getKind();
4104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Kind);
4105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (Kind) {
4106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateName::Template:
4107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(Name.getAsTemplateDecl(), Record);
4108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateName::OverloadedTemplate: {
4111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate();
4112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(OvT->size());
4113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (OverloadedTemplateStorage::iterator I = OvT->begin(), E = OvT->end();
4114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           I != E; ++I)
4115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(*I, Record);
4116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateName::QualifiedTemplate: {
4120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName();
4121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddNestedNameSpecifier(QualT->getQualifier(), Record);
4122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(QualT->hasTemplateKeyword());
4123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(QualT->getTemplateDecl(), Record);
4124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateName::DependentTemplate: {
4128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DependentTemplateName *DepT = Name.getAsDependentTemplateName();
4129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddNestedNameSpecifier(DepT->getQualifier(), Record);
4130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(DepT->isIdentifier());
4131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DepT->isIdentifier())
4132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddIdentifierRef(DepT->getIdentifier(), Record);
4133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    else
4134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(DepT->getOperator());
4135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateName::SubstTemplateTemplateParm: {
4139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SubstTemplateTemplateParmStorage *subst
4140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = Name.getAsSubstTemplateTemplateParm();
4141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(subst->getParameter(), Record);
4142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTemplateName(subst->getReplacement(), Record);
4143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateName::SubstTemplateTemplateParmPack: {
4147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SubstTemplateTemplateParmPackStorage *SubstPack
4148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = Name.getAsSubstTemplateTemplateParmPack();
4149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(SubstPack->getParameterPack(), Record);
4150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTemplateArgument(SubstPack->getArgumentPack(), Record);
4151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddTemplateArgument(const TemplateArgument &Arg,
4157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    RecordDataImpl &Record) {
4158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Arg.getKind());
4159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (Arg.getKind()) {
4160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Null:
4161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Type:
4163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTypeRef(Arg.getAsType(), Record);
4164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Declaration:
4166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(Arg.getAsDecl(), Record);
4167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Integral:
4169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddAPSInt(Arg.getAsIntegral(), Record);
4170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTypeRef(Arg.getIntegralType(), Record);
4171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Template:
4173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record);
4174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::TemplateExpansion:
4176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record);
4177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (llvm::Optional<unsigned> NumExpansions = Arg.getNumTemplateExpansions())
4178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(*NumExpansions + 1);
4179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    else
4180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(0);
4181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Expression:
4183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddStmt(Arg.getAsExpr());
4184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case TemplateArgument::Pack:
4186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Arg.pack_size());
4187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end();
4188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           I != E; ++I)
4189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddTemplateArgument(*I, Record);
4190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
4191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
4195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams,
4196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    RecordDataImpl &Record) {
4197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(TemplateParams && "No TemplateParams!");
4198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceLocation(TemplateParams->getTemplateLoc(), Record);
4199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceLocation(TemplateParams->getLAngleLoc(), Record);
4200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceLocation(TemplateParams->getRAngleLoc(), Record);
4201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TemplateParams->size());
4202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (TemplateParameterList::const_iterator
4203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         P = TemplateParams->begin(), PEnd = TemplateParams->end();
4204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         P != PEnd; ++P)
4205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(*P, Record);
4206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Emit a template argument list.
4209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
4210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
4211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   RecordDataImpl &Record) {
4212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(TemplateArgs && "No TemplateArgs!");
4213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(TemplateArgs->size());
4214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (int i=0, e = TemplateArgs->size(); i != e; ++i)
4215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddTemplateArgument(TemplateArgs->get(i), Record);
4216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
4220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record) {
4221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Set.size());
4222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (UnresolvedSetImpl::const_iterator
4223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         I = Set.begin(), E = Set.end(); I != E; ++I) {
4224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(I.getDecl(), Record);
4225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(I.getAccess());
4226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
4230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    RecordDataImpl &Record) {
4231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Base.isVirtual());
4232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Base.isBaseOfClass());
4233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Base.getAccessSpecifierAsWritten());
4234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Base.getInheritConstructors());
4235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddTypeSourceInfo(Base.getTypeSourceInfo(), Record);
4236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceRange(Base.getSourceRange(), Record);
4237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc()
4238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          : SourceLocation(),
4239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    Record);
4240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::FlushCXXBaseSpecifiers() {
4243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RecordData Record;
4244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) {
4245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.clear();
4246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Record the offset of this base-specifier set.
4248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned Index = CXXBaseSpecifiersToWrite[I].ID - 1;
4249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Index == CXXBaseSpecifiersOffsets.size())
4250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CXXBaseSpecifiersOffsets.push_back(Stream.GetCurrentBitNo());
4251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    else {
4252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Index > CXXBaseSpecifiersOffsets.size())
4253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        CXXBaseSpecifiersOffsets.resize(Index + 1);
4254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CXXBaseSpecifiersOffsets[Index] = Stream.GetCurrentBitNo();
4255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
4256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases,
4258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        *BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd;
4259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(BEnd - B);
4260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (; B != BEnd; ++B)
4261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddCXXBaseSpecifier(*B, Record);
4262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Stream.EmitRecord(serialization::DECL_CXX_BASE_SPECIFIERS, Record);
4263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Flush any expressions that were written as part of the base specifiers.
4265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FlushStmts();
4266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CXXBaseSpecifiersToWrite.clear();
4269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddCXXCtorInitializers(
4272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const CXXCtorInitializer * const *CtorInitializers,
4273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             unsigned NumCtorInitializers,
4274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             RecordDataImpl &Record) {
4275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(NumCtorInitializers);
4276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (unsigned i=0; i != NumCtorInitializers; ++i) {
4277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const CXXCtorInitializer *Init = CtorInitializers[i];
4278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Init->isBaseInitializer()) {
4280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(CTOR_INITIALIZER_BASE);
4281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddTypeSourceInfo(Init->getTypeSourceInfo(), Record);
4282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Init->isBaseVirtual());
4283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (Init->isDelegatingInitializer()) {
4284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(CTOR_INITIALIZER_DELEGATING);
4285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddTypeSourceInfo(Init->getTypeSourceInfo(), Record);
4286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (Init->isMemberInitializer()){
4287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(CTOR_INITIALIZER_MEMBER);
4288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(Init->getMember(), Record);
4289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
4290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(CTOR_INITIALIZER_INDIRECT_MEMBER);
4291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(Init->getIndirectMember(), Record);
4292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
4293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(Init->getMemberLocation(), Record);
4295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddStmt(Init->getInit());
4296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(Init->getLParenLoc(), Record);
4297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddSourceLocation(Init->getRParenLoc(), Record);
4298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Init->isWritten());
4299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (Init->isWritten()) {
4300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Init->getSourceOrder());
4301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
4302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Init->getNumArrayIndices());
4303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i)
4304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        AddDeclRef(Init->getArrayIndex(i), Record);
4305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
4306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) {
4310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(D->DefinitionData);
4311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
4312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.IsLambda);
4313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.UserDeclaredConstructor);
4314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.UserDeclaredCopyConstructor);
4315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.UserDeclaredMoveConstructor);
4316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.UserDeclaredCopyAssignment);
4317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.UserDeclaredMoveAssignment);
4318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.UserDeclaredDestructor);
4319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.Aggregate);
4320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.PlainOldData);
4321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.Empty);
4322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.Polymorphic);
4323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.Abstract);
4324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.IsStandardLayout);
4325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasNoNonEmptyBases);
4326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasPrivateFields);
4327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasProtectedFields);
4328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasPublicFields);
4329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasMutableFields);
4330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasOnlyCMembers);
4331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasInClassInitializer);
4332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasTrivialDefaultConstructor);
4333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasConstexprNonCopyMoveConstructor);
4334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.DefaultedDefaultConstructorIsConstexpr);
4335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasConstexprDefaultConstructor);
4336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasTrivialCopyConstructor);
4337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasTrivialMoveConstructor);
4338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasTrivialCopyAssignment);
4339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasTrivialMoveAssignment);
4340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasTrivialDestructor);
4341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasIrrelevantDestructor);
4342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.HasNonLiteralTypeFieldsOrBases);
4343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.ComputedVisibleConversions);
4344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.UserProvidedDefaultConstructor);
4345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.DeclaredDefaultConstructor);
4346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.DeclaredCopyConstructor);
4347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.DeclaredMoveConstructor);
4348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.DeclaredCopyAssignment);
4349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.DeclaredMoveAssignment);
4350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.DeclaredDestructor);
4351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.FailedImplicitMoveConstructor);
4352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.FailedImplicitMoveAssignment);
4353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // IsLambda bit is already saved.
4354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.NumBases);
4356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Data.NumBases > 0)
4357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases,
4358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            Record);
4359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: Make VBases lazily computed when needed to avoid storing them.
4361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(Data.NumVBases);
4362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Data.NumVBases > 0)
4363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases,
4364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            Record);
4365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddUnresolvedSet(Data.Conversions, Record);
4367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddUnresolvedSet(Data.VisibleConversions, Record);
4368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Data.Definition is the owning decl, no need to write it.
4369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddDeclRef(Data.FirstFriend, Record);
4370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Add lambda-specific data.
4372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Data.IsLambda) {
4373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData();
4374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Lambda.Dependent);
4375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Lambda.NumCaptures);
4376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Lambda.NumExplicitCaptures);
4377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Record.push_back(Lambda.ManglingNumber);
4378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AddDeclRef(Lambda.ContextDecl, Record);
4379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
4380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LambdaExpr::Capture &Capture = Lambda.Captures[I];
4381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceLocation(Capture.getLocation(), Record);
4382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Capture.isImplicit());
4383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Record.push_back(Capture.getCaptureKind()); // FIXME: stable!
4384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VarDecl *Var = Capture.capturesVariable()? Capture.getCapturedVar() : 0;
4385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddDeclRef(Var, Record);
4386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AddSourceLocation(Capture.isPackExpansion()? Capture.getEllipsisLoc()
4387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 : SourceLocation(),
4388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        Record);
4389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
4390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::ReaderInitialized(ASTReader *Reader) {
4394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(Reader && "Cannot remove chain");
4395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert((!Chain || Chain == Reader) && "Cannot replace chain");
4396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(FirstDeclID == NextDeclID &&
4397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FirstTypeID == NextTypeID &&
4398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FirstIdentID == NextIdentID &&
4399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FirstSubmoduleID == NextSubmoduleID &&
4400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FirstSelectorID == NextSelectorID &&
4401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "Setting chain after writing has started.");
4402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Chain = Reader;
4404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();
4406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();
4407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers();
4408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
4409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
4410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  NextDeclID = FirstDeclID;
4411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  NextTypeID = FirstTypeID;
4412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  NextIdentID = FirstIdentID;
4413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  NextSelectorID = FirstSelectorID;
4414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  NextSubmoduleID = FirstSubmoduleID;
4415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {
4418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  IdentifierIDs[II] = ID;
4419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (II->hasMacroDefinition())
4420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DeserializedMacroNames.push_back(II);
4421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
4424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Always take the highest-numbered type index. This copes with an interesting
4425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // case for chained AST writing where we schedule writing the type and then,
4426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // later, deserialize the type from another AST. In this case, we want to
4427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // keep the higher-numbered entry so that we can properly write it out to
4428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // the AST file.
4429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TypeIdx &StoredIdx = TypeIdxs[T];
4430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (Idx.getIndex() >= StoredIdx.getIndex())
4431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    StoredIdx = Idx;
4432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::SelectorRead(SelectorID ID, Selector S) {
4435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SelectorIDs[S] = ID;
4436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID,
4439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    MacroDefinition *MD) {
4440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(MacroDefinitions.find(MD) == MacroDefinitions.end());
4441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MacroDefinitions[MD] = ID;
4442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::MacroVisible(IdentifierInfo *II) {
4445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DeserializedMacroNames.push_back(II);
4446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) {
4449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(SubmoduleIDs.find(Mod) == SubmoduleIDs.end());
4450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SubmoduleIDs[Mod] = ID;
4451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::CompletedTagDefinition(const TagDecl *D) {
4454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(D->isCompleteDefinition());
4455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!WritingAST && "Already writing the AST!");
4456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
4457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // We are interested when a PCH decl is modified.
4458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (RD->isFromASTFile()) {
4459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // A forward reference was mutated into a definition. Rewrite it.
4460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // FIXME: This happens during template instantiation, should we
4461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // have created a new definition decl instead ?
4462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      RewriteDecl(RD);
4463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
4464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
4465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
4467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!WritingAST && "Already writing the AST!");
4468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // TU and namespaces are handled elsewhere.
4470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC))
4471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return;
4472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!(!D->isFromASTFile() && cast<Decl>(DC)->isFromASTFile()))
4474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return; // Not a source decl added to a DeclContext from PCH.
4475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AddUpdatedDeclContext(DC);
4477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
4480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!WritingAST && "Already writing the AST!");
4481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(D->isImplicit());
4482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!(!D->isFromASTFile() && RD->isFromASTFile()))
4483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return; // Not a source member added to a class from PCH.
4484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!isa<CXXMethodDecl>(D))
4485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return; // We are interested in lazily declared implicit methods.
4486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // A decl coming from PCH was modified.
4488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(RD->isCompleteDefinition());
4489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  UpdateRecord &Record = DeclUpdates[RD];
4490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER);
4491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(reinterpret_cast<uint64_t>(D));
4492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
4495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const ClassTemplateSpecializationDecl *D) {
4496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // The specializations set is kept in the canonical template.
4497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!WritingAST && "Already writing the AST!");
4498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TD = TD->getCanonicalDecl();
4499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!(!D->isFromASTFile() && TD->isFromASTFile()))
4500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return; // Not a source specialization added to a template from PCH.
4501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  UpdateRecord &Record = DeclUpdates[TD];
4503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION);
4504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(reinterpret_cast<uint64_t>(D));
4505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
4508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               const FunctionDecl *D) {
4509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // The specializations set is kept in the canonical template.
4510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!WritingAST && "Already writing the AST!");
4511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TD = TD->getCanonicalDecl();
4512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!(!D->isFromASTFile() && TD->isFromASTFile()))
4513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return; // Not a source specialization added to a template from PCH.
4514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  UpdateRecord &Record = DeclUpdates[TD];
4516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION);
4517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Record.push_back(reinterpret_cast<uint64_t>(D));
4518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
4521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(!WritingAST && "Already writing the AST!");
4522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!D->isFromASTFile())
4523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return; // Declaration not imported from PCH.
4524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Implicit decl from a PCH was defined.
4526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // FIXME: Should implicit definition be a separate FunctionDecl?
4527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RewriteDecl(D);
4528}
4529
4530void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
4531  assert(!WritingAST && "Already writing the AST!");
4532  if (!D->isFromASTFile())
4533    return;
4534
4535  // Since the actual instantiation is delayed, this really means that we need
4536  // to update the instantiation location.
4537  UpdateRecord &Record = DeclUpdates[D];
4538  Record.push_back(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER);
4539  AddSourceLocation(
4540      D->getMemberSpecializationInfo()->getPointOfInstantiation(), Record);
4541}
4542
4543void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
4544                                             const ObjCInterfaceDecl *IFD) {
4545  assert(!WritingAST && "Already writing the AST!");
4546  if (!IFD->isFromASTFile())
4547    return; // Declaration not imported from PCH.
4548
4549  assert(IFD->getDefinition() && "Category on a class without a definition?");
4550  ObjCClassesWithCategories.insert(
4551    const_cast<ObjCInterfaceDecl *>(IFD->getDefinition()));
4552}
4553
4554
4555void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
4556                                          const ObjCPropertyDecl *OrigProp,
4557                                          const ObjCCategoryDecl *ClassExt) {
4558  const ObjCInterfaceDecl *D = ClassExt->getClassInterface();
4559  if (!D)
4560    return;
4561
4562  assert(!WritingAST && "Already writing the AST!");
4563  if (!D->isFromASTFile())
4564    return; // Declaration not imported from PCH.
4565
4566  RewriteDecl(D);
4567}
4568