ASTWriter.cpp revision 953c564288f2f376fed9c3540096bde3694bbb7a
13a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===--- ASTWriter.cpp - AST File Writer ----------------------------------===// 23a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// 33a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// The LLVM Compiler Infrastructure 43a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// 53a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// This file is distributed under the University of Illinois Open Source 63a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// License. See LICENSE.TXT for details. 73a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// 83a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 93a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// 103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// This file defines the ASTWriter class, which writes AST files. 113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// 123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Serialization/ASTWriter.h" 153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Serialization/ASTSerializationListener.h" 163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "ASTCommon.h" 173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Sema/Sema.h" 183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Sema/IdentifierResolver.h" 193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/ASTContext.h" 203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/Decl.h" 213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/DeclContextInternals.h" 223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/DeclTemplate.h" 233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/DeclFriend.h" 243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/Expr.h" 253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/ExprCXX.h" 263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/Type.h" 273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/TypeLocVisitor.h" 283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Serialization/ASTReader.h" 293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Lex/MacroInfo.h" 303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Lex/PreprocessingRecord.h" 313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Lex/Preprocessor.h" 323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Lex/HeaderSearch.h" 333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/FileManager.h" 343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/FileSystemStatCache.h" 353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/OnDiskHashTable.h" 363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/SourceManager.h" 373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/SourceManagerInternals.h" 383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/TargetInfo.h" 393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/Version.h" 403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/Basic/VersionTuple.h" 413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "llvm/ADT/APFloat.h" 423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "llvm/ADT/APInt.h" 433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "llvm/ADT/StringExtras.h" 443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "llvm/Bitcode/BitstreamWriter.h" 453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "llvm/Support/FileSystem.h" 463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "llvm/Support/MemoryBuffer.h" 473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "llvm/Support/Path.h" 483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include <cstdio> 493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include <string.h> 503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgusing namespace clang; 513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgusing namespace clang::serialization; 523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgtemplate <typename T, typename Allocator> 543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic llvm::StringRef data(const std::vector<T, Allocator> &v) { 553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (v.empty()) return llvm::StringRef(); 563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return llvm::StringRef(reinterpret_cast<const char*>(&v[0]), 573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org sizeof(T) * v.size()); 583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgtemplate <typename T> 613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic llvm::StringRef data(const llvm::SmallVectorImpl<T> &v) { 623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return llvm::StringRef(reinterpret_cast<const char*>(v.data()), 633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org sizeof(T) * v.size()); 643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// Type serialization 683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgnamespace { 713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org class ASTTypeWriter { 723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTWriter &Writer; 733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTWriter::RecordDataImpl &Record; 743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org public: 763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /// \brief Type code that corresponds to the record generated. 773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org TypeCode Code; 783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) 803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { } 813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void VisitArrayType(const ArrayType *T); 833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void VisitFunctionType(const FunctionType *T); 843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void VisitTagType(const TagType *T); 853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T); 873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define ABSTRACT_TYPE(Class, Base) 883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/TypeNodes.def" 893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org }; 903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) { 933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org assert(false && "Built-in types are never serialized"); 943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitComplexType(const ComplexType *T) { 973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getElementType(), Record); 983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_COMPLEX; 993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitPointerType(const PointerType *T) { 1023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getPointeeType(), Record); 1033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_POINTER; 1043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { 1073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getPointeeType(), Record); 1083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_BLOCK_POINTER; 1093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) { 1123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record); 1133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->isSpelledAsLValue()); 1143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_LVALUE_REFERENCE; 1153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) { 1183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record); 1193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_RVALUE_REFERENCE; 1203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) { 1233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getPointeeType(), Record); 1243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(QualType(T->getClass(), 0), Record); 1253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_MEMBER_POINTER; 1263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitArrayType(const ArrayType *T) { 1293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getElementType(), Record); 1303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getSizeModifier()); // FIXME: stable values 1313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values 1323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) { 1353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayType(T); 1363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddAPInt(T->getSize(), Record); 1373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_CONSTANT_ARRAY; 1383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) { 1413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayType(T); 1423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_INCOMPLETE_ARRAY; 1433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { 1463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayType(T); 1473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(T->getLBracketLoc(), Record); 1483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(T->getRBracketLoc(), Record); 1493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddStmt(T->getSizeExpr()); 1503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_VARIABLE_ARRAY; 1513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitVectorType(const VectorType *T) { 1543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getElementType(), Record); 1553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getNumElements()); 1563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getVectorKind()); 1573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_VECTOR; 1583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) { 1613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitVectorType(T); 1623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_EXT_VECTOR; 1633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitFunctionType(const FunctionType *T) { 1663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getResultType(), Record); 1673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org FunctionType::ExtInfo C = T->getExtInfo(); 1683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(C.getNoReturn()); 1693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(C.getHasRegParm()); 1703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(C.getRegParm()); 1713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // FIXME: need to stabilize encoding of calling convention... 1723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(C.getCC()); 1733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { 1763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitFunctionType(T); 1773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_FUNCTION_NO_PROTO; 1783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { 1813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitFunctionType(T); 1823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getNumArgs()); 1833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I) 1843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getArgType(I), Record); 1853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->isVariadic()); 1863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getTypeQuals()); 1873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(static_cast<unsigned>(T->getRefQualifier())); 1883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getExceptionSpecType()); 1893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (T->getExceptionSpecType() == EST_Dynamic) { 1903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getNumExceptions()); 1913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) 1923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getExceptionType(I), Record); 1933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } else if (T->getExceptionSpecType() == EST_ComputedNoexcept) { 1943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddStmt(T->getNoexceptExpr()); 1953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 1963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_FUNCTION_PROTO; 1973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 2003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(T->getDecl(), Record); 2013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_UNRESOLVED_USING; 2023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitTypedefType(const TypedefType *T) { 2053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(T->getDecl(), Record); 2063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org assert(!T->isCanonicalUnqualified() && "Invalid typedef ?"); 2073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record); 2083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_TYPEDEF; 2093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) { 2123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddStmt(T->getUnderlyingExpr()); 2133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_TYPEOF_EXPR; 2143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) { 2173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getUnderlyingType(), Record); 2183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_TYPEOF; 2193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { 2223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddStmt(T->getUnderlyingExpr()); 2233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_DECLTYPE; 2243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitUnaryTransformType(const UnaryTransformType *T) { 2273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getBaseType(), Record); 2283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getUnderlyingType(), Record); 2293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getUTTKind()); 2303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_UNARY_TRANSFORM; 2313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitAutoType(const AutoType *T) { 2343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getDeducedType(), Record); 2353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_AUTO; 2363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitTagType(const TagType *T) { 2393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->isDependentType()); 2403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(T->getDecl(), Record); 2413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org assert(!T->isBeingDefined() && 2423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org "Cannot serialize in the middle of a type definition"); 2433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitRecordType(const RecordType *T) { 2463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitTagType(T); 2473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_RECORD; 2483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitEnumType(const EnumType *T) { 2513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitTagType(T); 2523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_ENUM; 2533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitAttributedType(const AttributedType *T) { 2563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getModifiedType(), Record); 2573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getEquivalentType(), Record); 2583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getAttrKind()); 2593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_ATTRIBUTED; 2603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 2633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitSubstTemplateTypeParmType( 2643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const SubstTemplateTypeParmType *T) { 2653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record); 2663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getReplacementType(), Record); 2673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_SUBST_TEMPLATE_TYPE_PARM; 2683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 2713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitSubstTemplateTypeParmPackType( 2723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const SubstTemplateTypeParmPackType *T) { 2733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record); 2743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTemplateArgument(T->getArgumentPack(), Record); 2753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK; 2763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 2793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitTemplateSpecializationType( 2803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const TemplateSpecializationType *T) { 2813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->isDependentType()); 2823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTemplateName(T->getTemplateName(), Record); 2833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getNumArgs()); 2843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end(); 2853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ArgI != ArgE; ++ArgI) 2863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTemplateArgument(*ArgI, Record); 2873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->isTypeAlias() ? T->getAliasedType() : 2883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org T->isCanonicalUnqualified() ? QualType() 2893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org : T->getCanonicalTypeInternal(), 2903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record); 2913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_TEMPLATE_SPECIALIZATION; 2923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 2953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 2963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayType(T); 2973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddStmt(T->getSizeExpr()); 2983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceRange(T->getBracketsRange(), Record); 2993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_DEPENDENT_SIZED_ARRAY; 3003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 3033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitDependentSizedExtVectorType( 3043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const DependentSizedExtVectorType *T) { 3053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // FIXME: Serialize this type (C++ only) 3063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org assert(false && "Cannot serialize dependent sized extended vector types"); 3073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 3103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 3113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getDepth()); 3123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getIndex()); 3133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->isParameterPack()); 3143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(T->getDecl(), Record); 3153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_TEMPLATE_TYPE_PARM; 3163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 3193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitDependentNameType(const DependentNameType *T) { 3203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getKeyword()); 3213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 3223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddIdentifierRef(T->getIdentifier(), Record); 3233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType() 3243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org : T->getCanonicalTypeInternal(), 3253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record); 3263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_DEPENDENT_NAME; 3273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 3303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitDependentTemplateSpecializationType( 3313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const DependentTemplateSpecializationType *T) { 3323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getKeyword()); 3333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 3343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddIdentifierRef(T->getIdentifier(), Record); 3353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getNumArgs()); 3363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (DependentTemplateSpecializationType::iterator 3373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org I = T->begin(), E = T->end(); I != E; ++I) 3383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTemplateArgument(*I, Record); 3393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION; 3403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitPackExpansionType(const PackExpansionType *T) { 3433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getPattern(), Record); 3443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (llvm::Optional<unsigned> NumExpansions = T->getNumExpansions()) 3453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(*NumExpansions + 1); 3463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org else 3473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(0); 3483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_PACK_EXPANSION; 3493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitParenType(const ParenType *T) { 3523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getInnerType(), Record); 3533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_PAREN; 3543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { 3573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getKeyword()); 3583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 3593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getNamedType(), Record); 3603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_ELABORATED; 3613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) { 3643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(T->getDecl(), Record); 3653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getInjectedSpecializationType(), Record); 3663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_INJECTED_CLASS_NAME; 3673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 3703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(T->getDecl(), Record); 3713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_OBJC_INTERFACE; 3723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) { 3753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getBaseType(), Record); 3763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(T->getNumProtocols()); 3773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (ObjCObjectType::qual_iterator I = T->qual_begin(), 3783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org E = T->qual_end(); I != E; ++I) 3793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(*I, Record); 3803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_OBJC_OBJECT; 3813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid 3843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 3853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeRef(T->getPointeeType(), Record); 3863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Code = TYPE_OBJC_OBJECT_POINTER; 3873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgnamespace { 3903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgclass TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { 3923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTWriter &Writer; 3933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTWriter::RecordDataImpl &Record; 3943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgpublic: 3963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) 3973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org : Writer(Writer), Record(Record) { } 3983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define ABSTRACT_TYPELOC(CLASS, PARENT) 4003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define TYPELOC(CLASS, PARENT) \ 4013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 4023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "clang/AST/TypeLocNodes.def" 4033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 4043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void VisitArrayTypeLoc(ArrayTypeLoc TyLoc); 4053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc); 4063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}; 4073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 4083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 4103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 4113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // nothing to do 4123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 4143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getBuiltinLoc(), Record); 4153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (TL.needsExtraLocalData()) { 4163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(TL.getWrittenTypeSpec()); 4173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(TL.getWrittenSignSpec()); 4183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(TL.getWrittenWidthSpec()); 4193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(TL.hasModeAttr()); 4203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 4213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { 4233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 4243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { 4263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getStarLoc(), Record); 4273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 4293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getCaretLoc(), Record); 4303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 4323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getAmpLoc(), Record); 4333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 4353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record); 4363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 4383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getStarLoc(), Record); 4393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeSourceInfo(TL.getClassTInfo(), Record); 4403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { 4423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLBracketLoc(), Record); 4433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRBracketLoc(), Record); 4443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(TL.getSizeExpr() ? 1 : 0); 4453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (TL.getSizeExpr()) 4463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddStmt(TL.getSizeExpr()); 4473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { 4493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayTypeLoc(TL); 4503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { 4523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayTypeLoc(TL); 4533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { 4553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayTypeLoc(TL); 4563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitDependentSizedArrayTypeLoc( 4583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org DependentSizedArrayTypeLoc TL) { 4593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitArrayTypeLoc(TL); 4603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( 4623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org DependentSizedExtVectorTypeLoc TL) { 4633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 4643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { 4663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 4673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { 4693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 4703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { 4723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLocalRangeBegin(), Record); 4733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLocalRangeEnd(), Record); 4743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(TL.getTrailingReturn()); 4753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 4763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddDeclRef(TL.getArg(i), Record); 4773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { 4793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitFunctionTypeLoc(TL); 4803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { 4823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org VisitFunctionTypeLoc(TL); 4833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 4853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 4863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 4883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 4893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 4913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 4923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLParenLoc(), Record); 4933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRParenLoc(), Record); 4943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 4953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 4963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 4973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLParenLoc(), Record); 4983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRParenLoc(), Record); 4993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record); 5003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 5023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { 5053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getKWLoc(), Record); 5063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLParenLoc(), Record); 5073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRParenLoc(), Record); 5083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record); 5093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { 5113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { 5143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { 5173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) { 5203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getAttrNameLoc(), Record); 5213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (TL.hasAttrOperand()) { 5223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org SourceRange range = TL.getAttrOperandParensRange(); 5233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(range.getBegin(), Record); 5243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(range.getEnd(), Record); 5253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 5263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (TL.hasAttrExprOperand()) { 5273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Expr *operand = TL.getAttrExprOperand(); 5283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(operand ? 1 : 0); 5293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (operand) Writer.AddStmt(operand); 5303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } else if (TL.hasAttrEnumOperand()) { 5313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getAttrEnumOperandLoc(), Record); 5323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 5333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 5353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( 5383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org SubstTemplateTypeParmTypeLoc TL) { 5393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc( 5423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org SubstTemplateTypeParmPackTypeLoc TL) { 5433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitTemplateSpecializationTypeLoc( 5463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org TemplateSpecializationTypeLoc TL) { 5473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record); 5483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 5493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 5503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 5513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(), 5523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org TL.getArgLoc(i).getLocInfo(), Record); 5533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) { 5553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLParenLoc(), Record); 5563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRParenLoc(), Record); 5573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { 5593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 5603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record); 5613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 5633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { 5663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 5673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record); 5683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( 5713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org DependentTemplateSpecializationTypeLoc TL) { 5723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 5733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record); 5743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 5763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 5773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) 5783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(), 5793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org TL.getArgLoc(I).getLocInfo(), Record); 5803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { 5823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getEllipsisLoc(), Record); 5833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 5853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getNameLoc(), Record); 5863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 5883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(TL.hasBaseTypeAsWritten()); 5893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 5903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 5913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) 5923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); 5933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 5953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Writer.AddSourceLocation(TL.getStarLoc(), Record); 5963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 5973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 5983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 5993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// ASTWriter Implementation 6003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 6013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 6023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void EmitBlockID(unsigned ID, const char *Name, 6033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::BitstreamWriter &Stream, 6043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTWriter::RecordDataImpl &Record) { 6053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.clear(); 6063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(ID); 6073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); 6083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 6093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Emit the block name if present. 6103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (Name == 0 || Name[0] == 0) return; 6113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.clear(); 6123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org while (*Name) 6133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(*Name++); 6143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record); 6153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 6163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 6173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void EmitRecordID(unsigned ID, const char *Name, 6183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::BitstreamWriter &Stream, 6193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTWriter::RecordDataImpl &Record) { 6203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.clear(); 6213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(ID); 6223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org while (*Name) 6233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(*Name++); 6243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record); 6253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 6263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 6273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void AddStmtsExprs(llvm::BitstreamWriter &Stream, 6283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ASTWriter::RecordDataImpl &Record) { 6293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 6303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_STOP); 6313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_NULL_PTR); 6323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_NULL); 6333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_COMPOUND); 6343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_CASE); 6353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_DEFAULT); 6363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_LABEL); 6373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_IF); 6383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_SWITCH); 6393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_WHILE); 6403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_DO); 6413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_FOR); 6423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_GOTO); 6433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_INDIRECT_GOTO); 6443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_CONTINUE); 6453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_BREAK); 6463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_RETURN); 6473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_DECL); 6483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_ASM); 6493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_PREDEFINED); 6503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_DECL_REF); 6513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_INTEGER_LITERAL); 6523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_FLOATING_LITERAL); 6533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_IMAGINARY_LITERAL); 6543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_STRING_LITERAL); 6553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CHARACTER_LITERAL); 6563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_PAREN); 6573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_UNARY_OPERATOR); 6583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_SIZEOF_ALIGN_OF); 6593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_ARRAY_SUBSCRIPT); 6603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CALL); 6613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_MEMBER); 6623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_BINARY_OPERATOR); 6633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR); 6643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CONDITIONAL_OPERATOR); 6653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_IMPLICIT_CAST); 6663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CSTYLE_CAST); 6673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_COMPOUND_LITERAL); 6683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_EXT_VECTOR_ELEMENT); 6693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_INIT_LIST); 6703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_DESIGNATED_INIT); 6713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_IMPLICIT_VALUE_INIT); 6723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_VA_ARG); 6733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_ADDR_LABEL); 6743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_STMT); 6753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CHOOSE); 6763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_GNU_NULL); 6773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_SHUFFLE_VECTOR); 6783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_BLOCK); 6793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_BLOCK_DECL_REF); 6803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_GENERIC_SELECTION); 6813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_STRING_LITERAL); 6823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_ENCODE); 6833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_SELECTOR_EXPR); 6843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_PROTOCOL_EXPR); 6853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_IVAR_REF_EXPR); 6863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_PROPERTY_REF_EXPR); 6873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_KVC_REF_EXPR); 6883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OBJC_MESSAGE_EXPR); 6893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_OBJC_FOR_COLLECTION); 6903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_OBJC_CATCH); 6913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_OBJC_FINALLY); 6923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_OBJC_AT_TRY); 6933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_OBJC_AT_SYNCHRONIZED); 6943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STMT_OBJC_AT_THROW); 6953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_OPERATOR_CALL); 6963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_CONSTRUCT); 6973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_STATIC_CAST); 6983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_DYNAMIC_CAST); 6993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_REINTERPRET_CAST); 7003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_CONST_CAST); 7013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_FUNCTIONAL_CAST); 7023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_BOOL_LITERAL); 7033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_NULL_PTR_LITERAL); 7043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_TYPEID_EXPR); 7053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_TYPEID_TYPE); 7063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_UUIDOF_EXPR); 7073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_UUIDOF_TYPE); 7083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_THIS); 7093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_THROW); 7103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_DEFAULT_ARG); 7113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_BIND_TEMPORARY); 7123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_SCALAR_VALUE_INIT); 7133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_NEW); 7143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_DELETE); 7153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_PSEUDO_DESTRUCTOR); 7163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_EXPR_WITH_CLEANUPS); 7173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_DEPENDENT_SCOPE_MEMBER); 7183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_DEPENDENT_SCOPE_DECL_REF); 7193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT); 7203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_UNRESOLVED_MEMBER); 7213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_UNRESOLVED_LOOKUP); 7223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_UNARY_TYPE_TRAIT); 7233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CXX_NOEXCEPT); 7243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_OPAQUE_VALUE); 7253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_BINARY_TYPE_TRAIT); 7263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_PACK_EXPANSION); 7273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_SIZEOF_PACK); 7283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK); 7293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXPR_CUDA_KERNEL_CALL); 7303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef RECORD 7313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 7323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 7333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTWriter::WriteBlockInfoBlock() { 7343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RecordData Record; 7353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3); 7363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 7373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record) 7383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 7393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 7403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // AST Top-Level Block. 7413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BLOCK(AST_BLOCK); 7423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(ORIGINAL_FILE_NAME); 7433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(ORIGINAL_FILE_ID); 7443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_OFFSET); 7453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OFFSET); 7463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(LANGUAGE_OPTIONS); 7473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(METADATA); 7483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(IDENTIFIER_OFFSET); 7493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(IDENTIFIER_TABLE); 7503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXTERNAL_DEFINITIONS); 7513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SPECIAL_TYPES); 7523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STATISTICS); 7533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TENTATIVE_DEFINITIONS); 7543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(UNUSED_FILESCOPED_DECLS); 7553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS); 7563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SELECTOR_OFFSETS); 7573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(METHOD_POOL); 7583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PP_COUNTER_VALUE); 7593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SOURCE_LOCATION_OFFSETS); 7603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SOURCE_LOCATION_PRELOADS); 7613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(STAT_CACHE); 7623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(EXT_VECTOR_DECLS); 7633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(VERSION_CONTROL_BRANCH_REVISION); 7643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(MACRO_DEFINITION_OFFSETS); 7653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(CHAINED_METADATA); 7663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(REFERENCED_SELECTOR_POOL); 7673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TU_UPDATE_LEXICAL); 7683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(REDECLS_UPDATE_LATEST); 7693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SEMA_DECL_REFS); 7703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(WEAK_UNDECLARED_IDENTIFIERS); 7713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PENDING_IMPLICIT_INSTANTIATIONS); 7723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_REPLACEMENTS); 7733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(UPDATE_VISIBLE); 7743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_UPDATE_OFFSETS); 7753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_UPDATES); 7763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(CXX_BASE_SPECIFIER_OFFSETS); 7773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DIAG_PRAGMA_MAPPINGS); 7783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(CUDA_SPECIAL_DECL_REFS); 7793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(HEADER_SEARCH_TABLE); 7803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(FP_PRAGMA_OPTIONS); 7813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(OPENCL_EXTENSIONS); 7823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DELEGATING_CTORS); 7833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 7843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // SourceManager Block. 7853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BLOCK(SOURCE_MANAGER_BLOCK); 7863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SM_SLOC_FILE_ENTRY); 7873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SM_SLOC_BUFFER_ENTRY); 7883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SM_SLOC_BUFFER_BLOB); 7893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SM_SLOC_INSTANTIATION_ENTRY); 7903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(SM_LINE_TABLE); 7913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 7923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Preprocessor Block. 7933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BLOCK(PREPROCESSOR_BLOCK); 7943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PP_MACRO_OBJECT_LIKE); 7953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PP_MACRO_FUNCTION_LIKE); 7963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PP_TOKEN); 7973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 7983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Decls and Types block. 7993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BLOCK(DECLTYPES_BLOCK); 8003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_EXT_QUAL); 8013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_COMPLEX); 8023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_POINTER); 8033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_BLOCK_POINTER); 8043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_LVALUE_REFERENCE); 8053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_RVALUE_REFERENCE); 8063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_MEMBER_POINTER); 8073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_CONSTANT_ARRAY); 8083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_INCOMPLETE_ARRAY); 8093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_VARIABLE_ARRAY); 8103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_VECTOR); 8113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_EXT_VECTOR); 8123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_FUNCTION_PROTO); 8133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_FUNCTION_NO_PROTO); 8143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_TYPEDEF); 8153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_TYPEOF_EXPR); 8163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_TYPEOF); 8173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_RECORD); 8183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_ENUM); 8193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_OBJC_INTERFACE); 8203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_OBJC_OBJECT); 8213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_OBJC_OBJECT_POINTER); 8223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_DECLTYPE); 8233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_ELABORATED); 8243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM); 8253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_UNRESOLVED_USING); 8263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_INJECTED_CLASS_NAME); 8273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_OBJC_OBJECT); 8283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_TEMPLATE_TYPE_PARM); 8293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_TEMPLATE_SPECIALIZATION); 8303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_DEPENDENT_NAME); 8313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION); 8323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_DEPENDENT_SIZED_ARRAY); 8333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_PAREN); 8343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_PACK_EXPANSION); 8353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_ATTRIBUTED); 8363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK); 8373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_TRANSLATION_UNIT); 8383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_TYPEDEF); 8393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_ENUM); 8403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_RECORD); 8413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_ENUM_CONSTANT); 8423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_FUNCTION); 8433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_METHOD); 8443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_INTERFACE); 8453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_PROTOCOL); 8463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_IVAR); 8473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_AT_DEFS_FIELD); 8483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_CLASS); 8493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_FORWARD_PROTOCOL); 8503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_CATEGORY); 8513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_CATEGORY_IMPL); 8523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_IMPLEMENTATION); 8533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_COMPATIBLE_ALIAS); 8543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_PROPERTY); 8553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_OBJC_PROPERTY_IMPL); 8563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_FIELD); 8573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_VAR); 8583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_IMPLICIT_PARAM); 8593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_PARM_VAR); 8603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_FILE_SCOPE_ASM); 8613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_BLOCK); 8623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CONTEXT_LEXICAL); 8633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CONTEXT_VISIBLE); 8643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_NAMESPACE); 8653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_NAMESPACE_ALIAS); 8663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_USING); 8673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_USING_SHADOW); 8683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_USING_DIRECTIVE); 8693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_UNRESOLVED_USING_VALUE); 8703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_UNRESOLVED_USING_TYPENAME); 8713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_LINKAGE_SPEC); 8723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CXX_RECORD); 8733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CXX_METHOD); 8743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CXX_CONSTRUCTOR); 8753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CXX_DESTRUCTOR); 8763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CXX_CONVERSION); 8773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_ACCESS_SPEC); 8783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_FRIEND); 8793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_FRIEND_TEMPLATE); 8803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CLASS_TEMPLATE); 8813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CLASS_TEMPLATE_SPECIALIZATION); 8823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION); 8833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_FUNCTION_TEMPLATE); 8843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_TEMPLATE_TYPE_PARM); 8853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_NON_TYPE_TEMPLATE_PARM); 8863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_TEMPLATE_TEMPLATE_PARM); 8873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_STATIC_ASSERT); 8883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_CXX_BASE_SPECIFIERS); 8893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_INDIRECTFIELD); 8903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK); 8913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 8923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Statements and Exprs can occur in the Decls and Types block. 8933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org AddStmtsExprs(Stream, Record); 8943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 8953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BLOCK(PREPROCESSOR_DETAIL_BLOCK); 8963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PPD_MACRO_INSTANTIATION); 8973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PPD_MACRO_DEFINITION); 8983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RECORD(PPD_INCLUSION_DIRECTIVE); 8993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef RECORD 9013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef BLOCK 9023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.ExitBlock(); 9033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 9043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// \brief Adjusts the given filename to only write out the portion of the 9063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// filename that is not part of the system root directory. 9073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// 9083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// \param Filename the file name to adjust. 9093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// 9103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and 9113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// the returned filename will be adjusted by this system root. 9123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// 9133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// \returns either the original filename (if it needs no adjustment) or the 9143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// adjusted filename (which points into the @p Filename parameter). 9153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic const char * 9163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgadjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) { 9173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org assert(Filename && "No file name to adjust?"); 9183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (!isysroot) 9203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return Filename; 9213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Verify that the filename and the system root have the same prefix. 9233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned Pos = 0; 9243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (; Filename[Pos] && isysroot[Pos]; ++Pos) 9253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (Filename[Pos] != isysroot[Pos]) 9263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return Filename; // Prefixes don't match. 9273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // We hit the end of the filename before we hit the end of the system root. 9293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (!Filename[Pos]) 9303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return Filename; 9313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // If the file name has a '/' at the current position, skip over the '/'. 9333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // We distinguish sysroot-based includes from absolute includes by the 9343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // absence of '/' at the beginning of sysroot-based includes. 9353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (Filename[Pos] == '/') 9363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ++Pos; 9373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return Filename + Pos; 9393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 9403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// \brief Write the AST metadata (e.g., i686-apple-darwin9). 9423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot, 9433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const std::string &OutputFile) { 9443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org using namespace llvm; 9453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Metadata 9473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const TargetInfo &Target = Context.Target; 9483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev(); 9493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MetaAbbrev->Add(BitCodeAbbrevOp( 9503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Chain ? CHAINED_METADATA : METADATA)); 9513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major 9523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor 9533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major 9543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor 9553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable 9563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Target triple or chained PCH name 9573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 9583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev); 9593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RecordData Record; 9613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(Chain ? CHAINED_METADATA : METADATA); 9623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(VERSION_MAJOR); 9633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(VERSION_MINOR); 9643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(CLANG_VERSION_MAJOR); 9653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(CLANG_VERSION_MINOR); 9663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(isysroot != 0); 9673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // FIXME: This writes the absolute path for chained headers. 9683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple(); 9693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr); 9703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Original file name and file ID 9723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org SourceManager &SM = Context.getSourceManager(); 9733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { 9743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev(); 9753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE_NAME)); 9763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 9773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev); 9783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::SmallString<128> MainFilePath(MainFile->getName()); 9803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::sys::fs::make_absolute(MainFilePath); 9823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const char *MainFileNameStr = MainFilePath.c_str(); 9843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, 9853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org isysroot); 9863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RecordData Record; 9873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(ORIGINAL_FILE_NAME); 9883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); 9893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.clear(); 9913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(SM.getMainFileID().getOpaqueValue()); 9923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecord(ORIGINAL_FILE_ID, Record); 9933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 9943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 9953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Original PCH directory 9963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (!OutputFile.empty() && OutputFile != "-") { 9973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 9983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR)); 9993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 10003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev); 10013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::SmallString<128> OutputPath(OutputFile); 10033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::sys::fs::make_absolute(OutputPath); 10053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org StringRef origDir = llvm::sys::path::parent_path(OutputPath); 10063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RecordData Record; 10083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(ORIGINAL_PCH_DIR); 10093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir); 10103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 10113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Repository branch/version information. 10133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev(); 10143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RepoAbbrev->Add(BitCodeAbbrevOp(VERSION_CONTROL_BRANCH_REVISION)); 10153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag 10163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev); 10173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.clear(); 10183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(VERSION_CONTROL_BRANCH_REVISION); 10193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecordWithBlob(RepoAbbrevCode, Record, 10203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org getClangFullRepositoryVersion()); 10213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 10223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// \brief Write the LangOptions structure. 10243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { 10253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RecordData Record; 10263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Trigraphs); 10273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments. 10283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers. 10293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode. 10303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc) 10313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.GNUKeywords); // Allow GNU-extension keywords 10323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'. 10333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Digraphs); // C94, C99 and C++ 10343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants. 10353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.C99); // C99 Support 10363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.C1X); // C1X Support 10373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Microsoft); // Microsoft extensions. 10383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // LangOpts.MSCVersion is ignored because all it does it set a macro, which is 10393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // already saved elsewhere. 10403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.CPlusPlus); // C++ Support 10413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support 10423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords. 10433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled. 10453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled. 10463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C 10473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // modern abi enabled. 10483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced 10493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // modern abi enabled. 10503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.AppleKext); // Apple's kernel extensions ABI 10513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ObjCDefaultSynthProperties); // Objective-C auto-synthesized 10523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // properties enabled. 10533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled.. 10543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings 10563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.WritableStrings); // Allow writable strings 10573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.LaxVectorConversions); 10583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.AltiVec); 10593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Exceptions); // Support exception handling. 10603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ObjCExceptions); 10613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.CXXExceptions); 10623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.SjLjExceptions); 10633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.MSBitfields); // MS-compatible structure layout 10653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime. 10663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Freestanding); // Freestanding implementation 10673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin) 10683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Whether static initializers are protected by locks. 10703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ThreadsafeStatics); 10713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.POSIXThreads); 10723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Blocks); // block extension to C 10733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if 10743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // they are unused. 10753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.MathErrno); // Math functions must respect errno 10763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // (modulo the platform support). 10773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.getSignedOverflowBehavior()); 10793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.HeinousExtensions); 10803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined. 10823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be 10833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // defined. 10843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as 10853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // opposed to __DYNAMIC__). 10863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero. 10873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 10883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be 10893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // used (instead of C99 semantics). 10903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined. 10913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.Deprecated); // Should __DEPRECATED be defined. 10923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.AccessControl); // Whether C++ access control should 10933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // be enabled. 10943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or 10953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // unsigned type 10963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ShortWChar); // force wchar_t to be unsigned short 10973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ShortEnums); // Should the enum type be equivalent 10983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // to the smallest integer type with 10993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // enough room. 11003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.getGCMode()); 11013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.getVisibilityMode()); 11023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.getStackProtectorMode()); 11033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.InstantiationDepth); 11043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.OpenCL); 11053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.CUDA); 11063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.CatchUndefined); 11073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.DefaultFPContract); 11083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.ElideConstructors); 11093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.SpellChecking); 11103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(LangOpts.MRTD); 11113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecord(LANGUAGE_OPTIONS, Record); 11123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 11133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 11153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// stat cache Serialization 11163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 11173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgnamespace { 11193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// Trait used for the on-disk hash table of stat cache results. 11203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgclass ASTStatCacheTrait { 11213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgpublic: 11223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org typedef const char * key_type; 11233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org typedef key_type key_type_ref; 11243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org typedef struct stat data_type; 11263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org typedef const data_type &data_type_ref; 11273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org static unsigned ComputeHash(const char *path) { 11293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return llvm::HashString(path); 11303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 11313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org std::pair<unsigned,unsigned> 11333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org EmitKeyDataLength(llvm::raw_ostream& Out, const char *path, 11343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org data_type_ref Data) { 11353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned StrLen = strlen(path); 11363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org clang::io::Emit16(Out, StrLen); 11373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned DataLen = 4 + 4 + 2 + 8 + 8; 11383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org clang::io::Emit8(Out, DataLen); 11393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return std::make_pair(StrLen + 1, DataLen); 11403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 11413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) { 11433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Out.write(path, KeyLen); 11443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 11453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org void EmitData(llvm::raw_ostream &Out, key_type_ref, 11473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org data_type_ref Data, unsigned DataLen) { 11483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org using namespace clang::io; 11493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org uint64_t Start = Out.tell(); (void)Start; 11503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Emit32(Out, (uint32_t) Data.st_ino); 11523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Emit32(Out, (uint32_t) Data.st_dev); 11533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Emit16(Out, (uint16_t) Data.st_mode); 11543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Emit64(Out, (uint64_t) Data.st_mtime); 11553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Emit64(Out, (uint64_t) Data.st_size); 11563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org assert(Out.tell() - Start == DataLen && "Wrong data length"); 11583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 11593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}; 11603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} // end anonymous namespace 11613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/// \brief Write the stat() system call cache to the AST file. 11633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) { 11643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Build the on-disk hash table containing information about every 11653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // stat() call. 11663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org OnDiskChainedHashTableGenerator<ASTStatCacheTrait> Generator; 11673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned NumStatEntries = 0; 11683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (MemorizeStatCalls::iterator Stat = StatCalls.begin(), 11693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org StatEnd = StatCalls.end(); 11703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stat != StatEnd; ++Stat, ++NumStatEntries) { 11713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org const char *Filename = Stat->first(); 11723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Generator.insert(Filename, Stat->second); 11733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 11743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Create the on-disk hash table in a buffer. 11763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::SmallString<4096> StatCacheData; 11773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org uint32_t BucketOffset; 11783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org { 11793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org llvm::raw_svector_ostream Out(StatCacheData); 11803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Make sure that no bucket is at offset 0 11813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org clang::io::Emit32(Out, 0); 11823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org BucketOffset = Generator.Emit(Out); 11833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 11843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Create a blob abbreviation 11863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org using namespace llvm; 1187760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 11883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Abbrev->Add(BitCodeAbbrevOp(STAT_CACHE)); 11893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 11903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 11913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 11923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev); 11933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 11943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org // Write the stat cache 11953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org RecordData Record; 11963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(STAT_CACHE); 11973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(BucketOffset); 11983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Record.push_back(NumStatEntries); 11993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str()); 12003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 12013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 12023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org//===----------------------------------------------------------------------===// 12033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org// Source Manager Serialization 1204//===----------------------------------------------------------------------===// 1205 1206/// \brief Create an abbreviation for the SLocEntry that refers to a 1207/// file. 1208static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { 1209 using namespace llvm; 1210 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1211 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY)); 1212 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1213 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 1214 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 1215 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1216 // FileEntry fields. 1217 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size 1218 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time 1219 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 1220 return Stream.EmitAbbrev(Abbrev); 1221} 1222 1223/// \brief Create an abbreviation for the SLocEntry that refers to a 1224/// buffer. 1225static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { 1226 using namespace llvm; 1227 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1228 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY)); 1229 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1230 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 1231 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 1232 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1233 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob 1234 return Stream.EmitAbbrev(Abbrev); 1235} 1236 1237/// \brief Create an abbreviation for the SLocEntry that refers to a 1238/// buffer's blob. 1239static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) { 1240 using namespace llvm; 1241 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1242 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_BLOB)); 1243 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob 1244 return Stream.EmitAbbrev(Abbrev); 1245} 1246 1247/// \brief Create an abbreviation for the SLocEntry that refers to an 1248/// buffer. 1249static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) { 1250 using namespace llvm; 1251 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1252 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_INSTANTIATION_ENTRY)); 1253 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1254 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location 1255 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location 1256 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location 1257 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length 1258 return Stream.EmitAbbrev(Abbrev); 1259} 1260 1261namespace { 1262 // Trait used for the on-disk hash table of header search information. 1263 class HeaderFileInfoTrait { 1264 ASTWriter &Writer; 1265 HeaderSearch &HS; 1266 1267 public: 1268 HeaderFileInfoTrait(ASTWriter &Writer, HeaderSearch &HS) 1269 : Writer(Writer), HS(HS) { } 1270 1271 typedef const char *key_type; 1272 typedef key_type key_type_ref; 1273 1274 typedef HeaderFileInfo data_type; 1275 typedef const data_type &data_type_ref; 1276 1277 static unsigned ComputeHash(const char *path) { 1278 // The hash is based only on the filename portion of the key, so that the 1279 // reader can match based on filenames when symlinking or excess path 1280 // elements ("foo/../", "../") change the form of the name. However, 1281 // complete path is still the key. 1282 return llvm::HashString(llvm::sys::path::filename(path)); 1283 } 1284 1285 std::pair<unsigned,unsigned> 1286 EmitKeyDataLength(llvm::raw_ostream& Out, const char *path, 1287 data_type_ref Data) { 1288 unsigned StrLen = strlen(path); 1289 clang::io::Emit16(Out, StrLen); 1290 unsigned DataLen = 1 + 2 + 4; 1291 clang::io::Emit8(Out, DataLen); 1292 return std::make_pair(StrLen + 1, DataLen); 1293 } 1294 1295 void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) { 1296 Out.write(path, KeyLen); 1297 } 1298 1299 void EmitData(llvm::raw_ostream &Out, key_type_ref, 1300 data_type_ref Data, unsigned DataLen) { 1301 using namespace clang::io; 1302 uint64_t Start = Out.tell(); (void)Start; 1303 1304 unsigned char Flags = (Data.isImport << 4) 1305 | (Data.isPragmaOnce << 3) 1306 | (Data.DirInfo << 1) 1307 | Data.Resolved; 1308 Emit8(Out, (uint8_t)Flags); 1309 Emit16(Out, (uint16_t) Data.NumIncludes); 1310 1311 if (!Data.ControllingMacro) 1312 Emit32(Out, (uint32_t)Data.ControllingMacroID); 1313 else 1314 Emit32(Out, (uint32_t)Writer.getIdentifierRef(Data.ControllingMacro)); 1315 assert(Out.tell() - Start == DataLen && "Wrong data length"); 1316 } 1317 }; 1318} // end anonymous namespace 1319 1320/// \brief Write the header search block for the list of files that 1321/// 1322/// \param HS The header search structure to save. 1323/// 1324/// \param Chain Whether we're creating a chained AST file. 1325void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, const char* isysroot) { 1326 llvm::SmallVector<const FileEntry *, 16> FilesByUID; 1327 HS.getFileMgr().GetUniqueIDMapping(FilesByUID); 1328 1329 if (FilesByUID.size() > HS.header_file_size()) 1330 FilesByUID.resize(HS.header_file_size()); 1331 1332 HeaderFileInfoTrait GeneratorTrait(*this, HS); 1333 OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator; 1334 llvm::SmallVector<const char *, 4> SavedStrings; 1335 unsigned NumHeaderSearchEntries = 0; 1336 for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) { 1337 const FileEntry *File = FilesByUID[UID]; 1338 if (!File) 1339 continue; 1340 1341 const HeaderFileInfo &HFI = HS.header_file_begin()[UID]; 1342 if (HFI.External && Chain) 1343 continue; 1344 1345 // Turn the file name into an absolute path, if it isn't already. 1346 const char *Filename = File->getName(); 1347 Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 1348 1349 // If we performed any translation on the file name at all, we need to 1350 // save this string, since the generator will refer to it later. 1351 if (Filename != File->getName()) { 1352 Filename = strdup(Filename); 1353 SavedStrings.push_back(Filename); 1354 } 1355 1356 Generator.insert(Filename, HFI, GeneratorTrait); 1357 ++NumHeaderSearchEntries; 1358 } 1359 1360 // Create the on-disk hash table in a buffer. 1361 llvm::SmallString<4096> TableData; 1362 uint32_t BucketOffset; 1363 { 1364 llvm::raw_svector_ostream Out(TableData); 1365 // Make sure that no bucket is at offset 0 1366 clang::io::Emit32(Out, 0); 1367 BucketOffset = Generator.Emit(Out, GeneratorTrait); 1368 } 1369 1370 // Create a blob abbreviation 1371 using namespace llvm; 1372 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1373 Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE)); 1374 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1375 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1376 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1377 unsigned TableAbbrev = Stream.EmitAbbrev(Abbrev); 1378 1379 // Write the stat cache 1380 RecordData Record; 1381 Record.push_back(HEADER_SEARCH_TABLE); 1382 Record.push_back(BucketOffset); 1383 Record.push_back(NumHeaderSearchEntries); 1384 Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData.str()); 1385 1386 // Free all of the strings we had to duplicate. 1387 for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I) 1388 free((void*)SavedStrings[I]); 1389} 1390 1391/// \brief Writes the block containing the serialized form of the 1392/// source manager. 1393/// 1394/// TODO: We should probably use an on-disk hash table (stored in a 1395/// blob), indexed based on the file name, so that we only create 1396/// entries for files that we actually need. In the common case (no 1397/// errors), we probably won't have to create file entries for any of 1398/// the files in the AST. 1399void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, 1400 const Preprocessor &PP, 1401 const char *isysroot) { 1402 RecordData Record; 1403 1404 // Enter the source manager block. 1405 Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 3); 1406 1407 // Abbreviations for the various kinds of source-location entries. 1408 unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream); 1409 unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream); 1410 unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream); 1411 unsigned SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream); 1412 1413 // Write the line table. 1414 if (SourceMgr.hasLineTable()) { 1415 LineTableInfo &LineTable = SourceMgr.getLineTable(); 1416 1417 // Emit the file names 1418 Record.push_back(LineTable.getNumFilenames()); 1419 for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) { 1420 // Emit the file name 1421 const char *Filename = LineTable.getFilename(I); 1422 Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 1423 unsigned FilenameLen = Filename? strlen(Filename) : 0; 1424 Record.push_back(FilenameLen); 1425 if (FilenameLen) 1426 Record.insert(Record.end(), Filename, Filename + FilenameLen); 1427 } 1428 1429 // Emit the line entries 1430 for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end(); 1431 L != LEnd; ++L) { 1432 // Emit the file ID 1433 Record.push_back(L->first); 1434 1435 // Emit the line entries 1436 Record.push_back(L->second.size()); 1437 for (std::vector<LineEntry>::iterator LE = L->second.begin(), 1438 LEEnd = L->second.end(); 1439 LE != LEEnd; ++LE) { 1440 Record.push_back(LE->FileOffset); 1441 Record.push_back(LE->LineNo); 1442 Record.push_back(LE->FilenameID); 1443 Record.push_back((unsigned)LE->FileKind); 1444 Record.push_back(LE->IncludeOffset); 1445 } 1446 } 1447 Stream.EmitRecord(SM_LINE_TABLE, Record); 1448 } 1449 1450 // Write out the source location entry table. We skip the first 1451 // entry, which is always the same dummy entry. 1452 std::vector<uint32_t> SLocEntryOffsets; 1453 // Write out the offsets of only source location file entries. 1454 // We will go through them in ASTReader::validateFileEntries(). 1455 std::vector<uint32_t> SLocFileEntryOffsets; 1456 RecordData PreloadSLocs; 1457 unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0; 1458 SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID); 1459 for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size(); 1460 I != N; ++I) { 1461 // Get this source location entry. 1462 const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I); 1463 1464 // Record the offset of this source-location entry. 1465 SLocEntryOffsets.push_back(Stream.GetCurrentBitNo()); 1466 1467 // Figure out which record code to use. 1468 unsigned Code; 1469 if (SLoc->isFile()) { 1470 if (SLoc->getFile().getContentCache()->OrigEntry) { 1471 Code = SM_SLOC_FILE_ENTRY; 1472 SLocFileEntryOffsets.push_back(Stream.GetCurrentBitNo()); 1473 } else 1474 Code = SM_SLOC_BUFFER_ENTRY; 1475 } else 1476 Code = SM_SLOC_INSTANTIATION_ENTRY; 1477 Record.clear(); 1478 Record.push_back(Code); 1479 1480 Record.push_back(SLoc->getOffset()); 1481 if (SLoc->isFile()) { 1482 const SrcMgr::FileInfo &File = SLoc->getFile(); 1483 Record.push_back(File.getIncludeLoc().getRawEncoding()); 1484 Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding 1485 Record.push_back(File.hasLineDirectives()); 1486 1487 const SrcMgr::ContentCache *Content = File.getContentCache(); 1488 if (Content->OrigEntry) { 1489 assert(Content->OrigEntry == Content->ContentsEntry && 1490 "Writing to AST an overriden file is not supported"); 1491 1492 // The source location entry is a file. The blob associated 1493 // with this entry is the file name. 1494 1495 // Emit size/modification time for this file. 1496 Record.push_back(Content->OrigEntry->getSize()); 1497 Record.push_back(Content->OrigEntry->getModificationTime()); 1498 1499 // Turn the file name into an absolute path, if it isn't already. 1500 const char *Filename = Content->OrigEntry->getName(); 1501 llvm::SmallString<128> FilePath(Filename); 1502 1503 // Ask the file manager to fixup the relative path for us. This will 1504 // honor the working directory. 1505 SourceMgr.getFileManager().FixupRelativePath(FilePath); 1506 1507 // FIXME: This call to make_absolute shouldn't be necessary, the 1508 // call to FixupRelativePath should always return an absolute path. 1509 llvm::sys::fs::make_absolute(FilePath); 1510 Filename = FilePath.c_str(); 1511 1512 Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 1513 Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename); 1514 } else { 1515 // The source location entry is a buffer. The blob associated 1516 // with this entry contains the contents of the buffer. 1517 1518 // We add one to the size so that we capture the trailing NULL 1519 // that is required by llvm::MemoryBuffer::getMemBuffer (on 1520 // the reader side). 1521 const llvm::MemoryBuffer *Buffer 1522 = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); 1523 const char *Name = Buffer->getBufferIdentifier(); 1524 Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record, 1525 llvm::StringRef(Name, strlen(Name) + 1)); 1526 Record.clear(); 1527 Record.push_back(SM_SLOC_BUFFER_BLOB); 1528 Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, 1529 llvm::StringRef(Buffer->getBufferStart(), 1530 Buffer->getBufferSize() + 1)); 1531 1532 if (strcmp(Name, "<built-in>") == 0) 1533 PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); 1534 } 1535 } else { 1536 // The source location entry is an instantiation. 1537 const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation(); 1538 Record.push_back(Inst.getSpellingLoc().getRawEncoding()); 1539 Record.push_back(Inst.getInstantiationLocStart().getRawEncoding()); 1540 Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding()); 1541 1542 // Compute the token length for this macro expansion. 1543 unsigned NextOffset = SourceMgr.getNextOffset(); 1544 if (I + 1 != N) 1545 NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset(); 1546 Record.push_back(NextOffset - SLoc->getOffset() - 1); 1547 Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record); 1548 } 1549 } 1550 1551 Stream.ExitBlock(); 1552 1553 if (SLocEntryOffsets.empty()) 1554 return; 1555 1556 // Write the source-location offsets table into the AST block. This 1557 // table is used for lazily loading source-location information. 1558 using namespace llvm; 1559 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1560 Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS)); 1561 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs 1562 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset 1563 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets 1564 unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev); 1565 1566 Record.clear(); 1567 Record.push_back(SOURCE_LOCATION_OFFSETS); 1568 Record.push_back(SLocEntryOffsets.size()); 1569 unsigned BaseOffset = Chain ? Chain->getNextSLocOffset() : 0; 1570 Record.push_back(SourceMgr.getNextOffset() - BaseOffset); 1571 Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets)); 1572 1573 Abbrev = new BitCodeAbbrev(); 1574 Abbrev->Add(BitCodeAbbrevOp(FILE_SOURCE_LOCATION_OFFSETS)); 1575 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs 1576 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets 1577 unsigned SLocFileOffsetsAbbrev = Stream.EmitAbbrev(Abbrev); 1578 1579 Record.clear(); 1580 Record.push_back(FILE_SOURCE_LOCATION_OFFSETS); 1581 Record.push_back(SLocFileEntryOffsets.size()); 1582 Stream.EmitRecordWithBlob(SLocFileOffsetsAbbrev, Record, 1583 data(SLocFileEntryOffsets)); 1584 1585 // Write the source location entry preloads array, telling the AST 1586 // reader which source locations entries it should load eagerly. 1587 Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs); 1588} 1589 1590//===----------------------------------------------------------------------===// 1591// Preprocessor Serialization 1592//===----------------------------------------------------------------------===// 1593 1594static int compareMacroDefinitions(const void *XPtr, const void *YPtr) { 1595 const std::pair<const IdentifierInfo *, MacroInfo *> &X = 1596 *(const std::pair<const IdentifierInfo *, MacroInfo *>*)XPtr; 1597 const std::pair<const IdentifierInfo *, MacroInfo *> &Y = 1598 *(const std::pair<const IdentifierInfo *, MacroInfo *>*)YPtr; 1599 return X.first->getName().compare(Y.first->getName()); 1600} 1601 1602/// \brief Writes the block containing the serialized form of the 1603/// preprocessor. 1604/// 1605void ASTWriter::WritePreprocessor(const Preprocessor &PP) { 1606 RecordData Record; 1607 1608 // If the preprocessor __COUNTER__ value has been bumped, remember it. 1609 if (PP.getCounterValue() != 0) { 1610 Record.push_back(PP.getCounterValue()); 1611 Stream.EmitRecord(PP_COUNTER_VALUE, Record); 1612 Record.clear(); 1613 } 1614 1615 // Enter the preprocessor block. 1616 Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3); 1617 1618 // If the AST file contains __DATE__ or __TIME__ emit a warning about this. 1619 // FIXME: use diagnostics subsystem for localization etc. 1620 if (PP.SawDateOrTime()) 1621 fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n"); 1622 1623 1624 // Loop over all the macro definitions that are live at the end of the file, 1625 // emitting each to the PP section. 1626 PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); 1627 1628 // Construct the list of macro definitions that need to be serialized. 1629 llvm::SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2> 1630 MacrosToEmit; 1631 llvm::SmallPtrSet<const IdentifierInfo*, 4> MacroDefinitionsSeen; 1632 for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0), 1633 E = PP.macro_end(Chain == 0); 1634 I != E; ++I) { 1635 MacroDefinitionsSeen.insert(I->first); 1636 MacrosToEmit.push_back(std::make_pair(I->first, I->second)); 1637 } 1638 1639 // Sort the set of macro definitions that need to be serialized by the 1640 // name of the macro, to provide a stable ordering. 1641 llvm::array_pod_sort(MacrosToEmit.begin(), MacrosToEmit.end(), 1642 &compareMacroDefinitions); 1643 1644 // Resolve any identifiers that defined macros at the time they were 1645 // deserialized, adding them to the list of macros to emit (if appropriate). 1646 for (unsigned I = 0, N = DeserializedMacroNames.size(); I != N; ++I) { 1647 IdentifierInfo *Name 1648 = const_cast<IdentifierInfo *>(DeserializedMacroNames[I]); 1649 if (Name->hasMacroDefinition() && MacroDefinitionsSeen.insert(Name)) 1650 MacrosToEmit.push_back(std::make_pair(Name, PP.getMacroInfo(Name))); 1651 } 1652 1653 for (unsigned I = 0, N = MacrosToEmit.size(); I != N; ++I) { 1654 const IdentifierInfo *Name = MacrosToEmit[I].first; 1655 MacroInfo *MI = MacrosToEmit[I].second; 1656 if (!MI) 1657 continue; 1658 1659 // Don't emit builtin macros like __LINE__ to the AST file unless they have 1660 // been redefined by the header (in which case they are not isBuiltinMacro). 1661 // Also skip macros from a AST file if we're chaining. 1662 1663 // FIXME: There is a (probably minor) optimization we could do here, if 1664 // the macro comes from the original PCH but the identifier comes from a 1665 // chained PCH, by storing the offset into the original PCH rather than 1666 // writing the macro definition a second time. 1667 if (MI->isBuiltinMacro() || 1668 (Chain && Name->isFromAST() && MI->isFromAST())) 1669 continue; 1670 1671 AddIdentifierRef(Name, Record); 1672 MacroOffsets[Name] = Stream.GetCurrentBitNo(); 1673 Record.push_back(MI->getDefinitionLoc().getRawEncoding()); 1674 Record.push_back(MI->isUsed()); 1675 1676 unsigned Code; 1677 if (MI->isObjectLike()) { 1678 Code = PP_MACRO_OBJECT_LIKE; 1679 } else { 1680 Code = PP_MACRO_FUNCTION_LIKE; 1681 1682 Record.push_back(MI->isC99Varargs()); 1683 Record.push_back(MI->isGNUVarargs()); 1684 Record.push_back(MI->getNumArgs()); 1685 for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end(); 1686 I != E; ++I) 1687 AddIdentifierRef(*I, Record); 1688 } 1689 1690 // If we have a detailed preprocessing record, record the macro definition 1691 // ID that corresponds to this macro. 1692 if (PPRec) 1693 Record.push_back(getMacroDefinitionID(PPRec->findMacroDefinition(MI))); 1694 1695 Stream.EmitRecord(Code, Record); 1696 Record.clear(); 1697 1698 // Emit the tokens array. 1699 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) { 1700 // Note that we know that the preprocessor does not have any annotation 1701 // tokens in it because they are created by the parser, and thus can't be 1702 // in a macro definition. 1703 const Token &Tok = MI->getReplacementToken(TokNo); 1704 1705 Record.push_back(Tok.getLocation().getRawEncoding()); 1706 Record.push_back(Tok.getLength()); 1707 1708 // FIXME: When reading literal tokens, reconstruct the literal pointer if 1709 // it is needed. 1710 AddIdentifierRef(Tok.getIdentifierInfo(), Record); 1711 // FIXME: Should translate token kind to a stable encoding. 1712 Record.push_back(Tok.getKind()); 1713 // FIXME: Should translate token flags to a stable encoding. 1714 Record.push_back(Tok.getFlags()); 1715 1716 Stream.EmitRecord(PP_TOKEN, Record); 1717 Record.clear(); 1718 } 1719 ++NumMacros; 1720 } 1721 Stream.ExitBlock(); 1722 1723 if (PPRec) 1724 WritePreprocessorDetail(*PPRec); 1725} 1726 1727void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { 1728 if (PPRec.begin(Chain) == PPRec.end(Chain)) 1729 return; 1730 1731 // Enter the preprocessor block. 1732 Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3); 1733 1734 // If the preprocessor has a preprocessing record, emit it. 1735 unsigned NumPreprocessingRecords = 0; 1736 using namespace llvm; 1737 1738 // Set up the abbreviation for 1739 unsigned InclusionAbbrev = 0; 1740 { 1741 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1742 Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE)); 1743 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index 1744 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location 1745 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location 1746 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length 1747 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes 1748 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind 1749 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1750 InclusionAbbrev = Stream.EmitAbbrev(Abbrev); 1751 } 1752 1753 unsigned IndexBase = Chain ? PPRec.getNumPreallocatedEntities() : 0; 1754 RecordData Record; 1755 for (PreprocessingRecord::iterator E = PPRec.begin(Chain), 1756 EEnd = PPRec.end(Chain); 1757 E != EEnd; ++E) { 1758 Record.clear(); 1759 1760 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { 1761 // Record this macro definition's location. 1762 MacroID ID = getMacroDefinitionID(MD); 1763 1764 // Don't write the macro definition if it is from another AST file. 1765 if (ID < FirstMacroID) 1766 continue; 1767 1768 // Notify the serialization listener that we're serializing this entity. 1769 if (SerializationListener) 1770 SerializationListener->SerializedPreprocessedEntity(*E, 1771 Stream.GetCurrentBitNo()); 1772 1773 unsigned Position = ID - FirstMacroID; 1774 if (Position != MacroDefinitionOffsets.size()) { 1775 if (Position > MacroDefinitionOffsets.size()) 1776 MacroDefinitionOffsets.resize(Position + 1); 1777 1778 MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo(); 1779 } else 1780 MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); 1781 1782 Record.push_back(IndexBase + NumPreprocessingRecords++); 1783 Record.push_back(ID); 1784 AddSourceLocation(MD->getSourceRange().getBegin(), Record); 1785 AddSourceLocation(MD->getSourceRange().getEnd(), Record); 1786 AddIdentifierRef(MD->getName(), Record); 1787 AddSourceLocation(MD->getLocation(), Record); 1788 Stream.EmitRecord(PPD_MACRO_DEFINITION, Record); 1789 continue; 1790 } 1791 1792 // Notify the serialization listener that we're serializing this entity. 1793 if (SerializationListener) 1794 SerializationListener->SerializedPreprocessedEntity(*E, 1795 Stream.GetCurrentBitNo()); 1796 1797 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { 1798 Record.push_back(IndexBase + NumPreprocessingRecords++); 1799 AddSourceLocation(MI->getSourceRange().getBegin(), Record); 1800 AddSourceLocation(MI->getSourceRange().getEnd(), Record); 1801 AddIdentifierRef(MI->getName(), Record); 1802 Record.push_back(getMacroDefinitionID(MI->getDefinition())); 1803 Stream.EmitRecord(PPD_MACRO_INSTANTIATION, Record); 1804 continue; 1805 } 1806 1807 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { 1808 Record.push_back(PPD_INCLUSION_DIRECTIVE); 1809 Record.push_back(IndexBase + NumPreprocessingRecords++); 1810 AddSourceLocation(ID->getSourceRange().getBegin(), Record); 1811 AddSourceLocation(ID->getSourceRange().getEnd(), Record); 1812 Record.push_back(ID->getFileName().size()); 1813 Record.push_back(ID->wasInQuotes()); 1814 Record.push_back(static_cast<unsigned>(ID->getKind())); 1815 llvm::SmallString<64> Buffer; 1816 Buffer += ID->getFileName(); 1817 Buffer += ID->getFile()->getName(); 1818 Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); 1819 continue; 1820 } 1821 1822 llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter"); 1823 } 1824 Stream.ExitBlock(); 1825 1826 // Write the offsets table for the preprocessing record. 1827 if (NumPreprocessingRecords > 0) { 1828 // Write the offsets table for identifier IDs. 1829 using namespace llvm; 1830 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1831 Abbrev->Add(BitCodeAbbrevOp(MACRO_DEFINITION_OFFSETS)); 1832 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of records 1833 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs 1834 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1835 unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1836 1837 Record.clear(); 1838 Record.push_back(MACRO_DEFINITION_OFFSETS); 1839 Record.push_back(NumPreprocessingRecords); 1840 Record.push_back(MacroDefinitionOffsets.size()); 1841 Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record, 1842 data(MacroDefinitionOffsets)); 1843 } 1844} 1845 1846void ASTWriter::WritePragmaDiagnosticMappings(const Diagnostic &Diag) { 1847 RecordData Record; 1848 for (Diagnostic::DiagStatePointsTy::const_iterator 1849 I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end(); 1850 I != E; ++I) { 1851 const Diagnostic::DiagStatePoint &point = *I; 1852 if (point.Loc.isInvalid()) 1853 continue; 1854 1855 Record.push_back(point.Loc.getRawEncoding()); 1856 for (Diagnostic::DiagState::iterator 1857 I = point.State->begin(), E = point.State->end(); I != E; ++I) { 1858 unsigned diag = I->first, map = I->second; 1859 if (map & 0x10) { // mapping from a diagnostic pragma. 1860 Record.push_back(diag); 1861 Record.push_back(map & 0x7); 1862 } 1863 } 1864 Record.push_back(-1); // mark the end of the diag/map pairs for this 1865 // location. 1866 } 1867 1868 if (!Record.empty()) 1869 Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record); 1870} 1871 1872void ASTWriter::WriteCXXBaseSpecifiersOffsets() { 1873 if (CXXBaseSpecifiersOffsets.empty()) 1874 return; 1875 1876 RecordData Record; 1877 1878 // Create a blob abbreviation for the C++ base specifiers offsets. 1879 using namespace llvm; 1880 1881 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1882 Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS)); 1883 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size 1884 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1885 unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1886 1887 // Write the selector offsets table. 1888 Record.clear(); 1889 Record.push_back(CXX_BASE_SPECIFIER_OFFSETS); 1890 Record.push_back(CXXBaseSpecifiersOffsets.size()); 1891 Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, 1892 data(CXXBaseSpecifiersOffsets)); 1893} 1894 1895//===----------------------------------------------------------------------===// 1896// Type Serialization 1897//===----------------------------------------------------------------------===// 1898 1899/// \brief Write the representation of a type to the AST stream. 1900void ASTWriter::WriteType(QualType T) { 1901 TypeIdx &Idx = TypeIdxs[T]; 1902 if (Idx.getIndex() == 0) // we haven't seen this type before. 1903 Idx = TypeIdx(NextTypeID++); 1904 1905 assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); 1906 1907 // Record the offset for this type. 1908 unsigned Index = Idx.getIndex() - FirstTypeID; 1909 if (TypeOffsets.size() == Index) 1910 TypeOffsets.push_back(Stream.GetCurrentBitNo()); 1911 else if (TypeOffsets.size() < Index) { 1912 TypeOffsets.resize(Index + 1); 1913 TypeOffsets[Index] = Stream.GetCurrentBitNo(); 1914 } 1915 1916 RecordData Record; 1917 1918 // Emit the type's representation. 1919 ASTTypeWriter W(*this, Record); 1920 1921 if (T.hasLocalNonFastQualifiers()) { 1922 Qualifiers Qs = T.getLocalQualifiers(); 1923 AddTypeRef(T.getLocalUnqualifiedType(), Record); 1924 Record.push_back(Qs.getAsOpaqueValue()); 1925 W.Code = TYPE_EXT_QUAL; 1926 } else { 1927 switch (T->getTypeClass()) { 1928 // For all of the concrete, non-dependent types, call the 1929 // appropriate visitor function. 1930#define TYPE(Class, Base) \ 1931 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break; 1932#define ABSTRACT_TYPE(Class, Base) 1933#include "clang/AST/TypeNodes.def" 1934 } 1935 } 1936 1937 // Emit the serialized record. 1938 Stream.EmitRecord(W.Code, Record); 1939 1940 // Flush any expressions that were written as part of this type. 1941 FlushStmts(); 1942} 1943 1944//===----------------------------------------------------------------------===// 1945// Declaration Serialization 1946//===----------------------------------------------------------------------===// 1947 1948/// \brief Write the block containing all of the declaration IDs 1949/// lexically declared within the given DeclContext. 1950/// 1951/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the 1952/// bistream, or 0 if no block was written. 1953uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, 1954 DeclContext *DC) { 1955 if (DC->decls_empty()) 1956 return 0; 1957 1958 uint64_t Offset = Stream.GetCurrentBitNo(); 1959 RecordData Record; 1960 Record.push_back(DECL_CONTEXT_LEXICAL); 1961 llvm::SmallVector<KindDeclIDPair, 64> Decls; 1962 for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); 1963 D != DEnd; ++D) 1964 Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D))); 1965 1966 ++NumLexicalDeclContexts; 1967 Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, data(Decls)); 1968 return Offset; 1969} 1970 1971void ASTWriter::WriteTypeDeclOffsets() { 1972 using namespace llvm; 1973 RecordData Record; 1974 1975 // Write the type offsets array 1976 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1977 Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET)); 1978 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types 1979 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block 1980 unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1981 Record.clear(); 1982 Record.push_back(TYPE_OFFSET); 1983 Record.push_back(TypeOffsets.size()); 1984 Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, data(TypeOffsets)); 1985 1986 // Write the declaration offsets array 1987 Abbrev = new BitCodeAbbrev(); 1988 Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); 1989 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations 1990 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block 1991 unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1992 Record.clear(); 1993 Record.push_back(DECL_OFFSET); 1994 Record.push_back(DeclOffsets.size()); 1995 Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets)); 1996} 1997 1998//===----------------------------------------------------------------------===// 1999// Global Method Pool and Selector Serialization 2000//===----------------------------------------------------------------------===// 2001 2002namespace { 2003// Trait used for the on-disk hash table used in the method pool. 2004class ASTMethodPoolTrait { 2005 ASTWriter &Writer; 2006 2007public: 2008 typedef Selector key_type; 2009 typedef key_type key_type_ref; 2010 2011 struct data_type { 2012 SelectorID ID; 2013 ObjCMethodList Instance, Factory; 2014 }; 2015 typedef const data_type& data_type_ref; 2016 2017 explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { } 2018 2019 static unsigned ComputeHash(Selector Sel) { 2020 return serialization::ComputeHash(Sel); 2021 } 2022 2023 std::pair<unsigned,unsigned> 2024 EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel, 2025 data_type_ref Methods) { 2026 unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4); 2027 clang::io::Emit16(Out, KeyLen); 2028 unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts 2029 for (const ObjCMethodList *Method = &Methods.Instance; Method; 2030 Method = Method->Next) 2031 if (Method->Method) 2032 DataLen += 4; 2033 for (const ObjCMethodList *Method = &Methods.Factory; Method; 2034 Method = Method->Next) 2035 if (Method->Method) 2036 DataLen += 4; 2037 clang::io::Emit16(Out, DataLen); 2038 return std::make_pair(KeyLen, DataLen); 2039 } 2040 2041 void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) { 2042 uint64_t Start = Out.tell(); 2043 assert((Start >> 32) == 0 && "Selector key offset too large"); 2044 Writer.SetSelectorOffset(Sel, Start); 2045 unsigned N = Sel.getNumArgs(); 2046 clang::io::Emit16(Out, N); 2047 if (N == 0) 2048 N = 1; 2049 for (unsigned I = 0; I != N; ++I) 2050 clang::io::Emit32(Out, 2051 Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I))); 2052 } 2053 2054 void EmitData(llvm::raw_ostream& Out, key_type_ref, 2055 data_type_ref Methods, unsigned DataLen) { 2056 uint64_t Start = Out.tell(); (void)Start; 2057 clang::io::Emit32(Out, Methods.ID); 2058 unsigned NumInstanceMethods = 0; 2059 for (const ObjCMethodList *Method = &Methods.Instance; Method; 2060 Method = Method->Next) 2061 if (Method->Method) 2062 ++NumInstanceMethods; 2063 2064 unsigned NumFactoryMethods = 0; 2065 for (const ObjCMethodList *Method = &Methods.Factory; Method; 2066 Method = Method->Next) 2067 if (Method->Method) 2068 ++NumFactoryMethods; 2069 2070 clang::io::Emit16(Out, NumInstanceMethods); 2071 clang::io::Emit16(Out, NumFactoryMethods); 2072 for (const ObjCMethodList *Method = &Methods.Instance; Method; 2073 Method = Method->Next) 2074 if (Method->Method) 2075 clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 2076 for (const ObjCMethodList *Method = &Methods.Factory; Method; 2077 Method = Method->Next) 2078 if (Method->Method) 2079 clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 2080 2081 assert(Out.tell() - Start == DataLen && "Data length is wrong"); 2082 } 2083}; 2084} // end anonymous namespace 2085 2086/// \brief Write ObjC data: selectors and the method pool. 2087/// 2088/// The method pool contains both instance and factory methods, stored 2089/// in an on-disk hash table indexed by the selector. The hash table also 2090/// contains an empty entry for every other selector known to Sema. 2091void ASTWriter::WriteSelectors(Sema &SemaRef) { 2092 using namespace llvm; 2093 2094 // Do we have to do anything at all? 2095 if (SemaRef.MethodPool.empty() && SelectorIDs.empty()) 2096 return; 2097 unsigned NumTableEntries = 0; 2098 // Create and write out the blob that contains selectors and the method pool. 2099 { 2100 OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator; 2101 ASTMethodPoolTrait Trait(*this); 2102 2103 // Create the on-disk hash table representation. We walk through every 2104 // selector we've seen and look it up in the method pool. 2105 SelectorOffsets.resize(NextSelectorID - FirstSelectorID); 2106 for (llvm::DenseMap<Selector, SelectorID>::iterator 2107 I = SelectorIDs.begin(), E = SelectorIDs.end(); 2108 I != E; ++I) { 2109 Selector S = I->first; 2110 Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); 2111 ASTMethodPoolTrait::data_type Data = { 2112 I->second, 2113 ObjCMethodList(), 2114 ObjCMethodList() 2115 }; 2116 if (F != SemaRef.MethodPool.end()) { 2117 Data.Instance = F->second.first; 2118 Data.Factory = F->second.second; 2119 } 2120 // Only write this selector if it's not in an existing AST or something 2121 // changed. 2122 if (Chain && I->second < FirstSelectorID) { 2123 // Selector already exists. Did it change? 2124 bool changed = false; 2125 for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method; 2126 M = M->Next) { 2127 if (M->Method->getPCHLevel() == 0) 2128 changed = true; 2129 } 2130 for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method; 2131 M = M->Next) { 2132 if (M->Method->getPCHLevel() == 0) 2133 changed = true; 2134 } 2135 if (!changed) 2136 continue; 2137 } else if (Data.Instance.Method || Data.Factory.Method) { 2138 // A new method pool entry. 2139 ++NumTableEntries; 2140 } 2141 Generator.insert(S, Data, Trait); 2142 } 2143 2144 // Create the on-disk hash table in a buffer. 2145 llvm::SmallString<4096> MethodPool; 2146 uint32_t BucketOffset; 2147 { 2148 ASTMethodPoolTrait Trait(*this); 2149 llvm::raw_svector_ostream Out(MethodPool); 2150 // Make sure that no bucket is at offset 0 2151 clang::io::Emit32(Out, 0); 2152 BucketOffset = Generator.Emit(Out, Trait); 2153 } 2154 2155 // Create a blob abbreviation 2156 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 2157 Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL)); 2158 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 2159 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 2160 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2161 unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev); 2162 2163 // Write the method pool 2164 RecordData Record; 2165 Record.push_back(METHOD_POOL); 2166 Record.push_back(BucketOffset); 2167 Record.push_back(NumTableEntries); 2168 Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str()); 2169 2170 // Create a blob abbreviation for the selector table offsets. 2171 Abbrev = new BitCodeAbbrev(); 2172 Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS)); 2173 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size 2174 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2175 unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 2176 2177 // Write the selector offsets table. 2178 Record.clear(); 2179 Record.push_back(SELECTOR_OFFSETS); 2180 Record.push_back(SelectorOffsets.size()); 2181 Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, 2182 data(SelectorOffsets)); 2183 } 2184} 2185 2186/// \brief Write the selectors referenced in @selector expression into AST file. 2187void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { 2188 using namespace llvm; 2189 if (SemaRef.ReferencedSelectors.empty()) 2190 return; 2191 2192 RecordData Record; 2193 2194 // Note: this writes out all references even for a dependent AST. But it is 2195 // very tricky to fix, and given that @selector shouldn't really appear in 2196 // headers, probably not worth it. It's not a correctness issue. 2197 for (DenseMap<Selector, SourceLocation>::iterator S = 2198 SemaRef.ReferencedSelectors.begin(), 2199 E = SemaRef.ReferencedSelectors.end(); S != E; ++S) { 2200 Selector Sel = (*S).first; 2201 SourceLocation Loc = (*S).second; 2202 AddSelectorRef(Sel, Record); 2203 AddSourceLocation(Loc, Record); 2204 } 2205 Stream.EmitRecord(REFERENCED_SELECTOR_POOL, Record); 2206} 2207 2208//===----------------------------------------------------------------------===// 2209// Identifier Table Serialization 2210//===----------------------------------------------------------------------===// 2211 2212namespace { 2213class ASTIdentifierTableTrait { 2214 ASTWriter &Writer; 2215 Preprocessor &PP; 2216 2217 /// \brief Determines whether this is an "interesting" identifier 2218 /// that needs a full IdentifierInfo structure written into the hash 2219 /// table. 2220 static bool isInterestingIdentifier(const IdentifierInfo *II) { 2221 return II->isPoisoned() || 2222 II->isExtensionToken() || 2223 II->hasMacroDefinition() || 2224 II->getObjCOrBuiltinID() || 2225 II->getFETokenInfo<void>(); 2226 } 2227 2228public: 2229 typedef const IdentifierInfo* key_type; 2230 typedef key_type key_type_ref; 2231 2232 typedef IdentID data_type; 2233 typedef data_type data_type_ref; 2234 2235 ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP) 2236 : Writer(Writer), PP(PP) { } 2237 2238 static unsigned ComputeHash(const IdentifierInfo* II) { 2239 return llvm::HashString(II->getName()); 2240 } 2241 2242 std::pair<unsigned,unsigned> 2243 EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II, 2244 IdentID ID) { 2245 unsigned KeyLen = II->getLength() + 1; 2246 unsigned DataLen = 4; // 4 bytes for the persistent ID << 1 2247 if (isInterestingIdentifier(II)) { 2248 DataLen += 2; // 2 bytes for builtin ID, flags 2249 if (II->hasMacroDefinition() && 2250 !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro()) 2251 DataLen += 4; 2252 for (IdentifierResolver::iterator D = IdentifierResolver::begin(II), 2253 DEnd = IdentifierResolver::end(); 2254 D != DEnd; ++D) 2255 DataLen += sizeof(DeclID); 2256 } 2257 clang::io::Emit16(Out, DataLen); 2258 // We emit the key length after the data length so that every 2259 // string is preceded by a 16-bit length. This matches the PTH 2260 // format for storing identifiers. 2261 clang::io::Emit16(Out, KeyLen); 2262 return std::make_pair(KeyLen, DataLen); 2263 } 2264 2265 void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II, 2266 unsigned KeyLen) { 2267 // Record the location of the key data. This is used when generating 2268 // the mapping from persistent IDs to strings. 2269 Writer.SetIdentifierOffset(II, Out.tell()); 2270 Out.write(II->getNameStart(), KeyLen); 2271 } 2272 2273 void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II, 2274 IdentID ID, unsigned) { 2275 if (!isInterestingIdentifier(II)) { 2276 clang::io::Emit32(Out, ID << 1); 2277 return; 2278 } 2279 2280 clang::io::Emit32(Out, (ID << 1) | 0x01); 2281 uint32_t Bits = 0; 2282 bool hasMacroDefinition = 2283 II->hasMacroDefinition() && 2284 !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro(); 2285 Bits = (uint32_t)II->getObjCOrBuiltinID(); 2286 Bits = (Bits << 1) | unsigned(hasMacroDefinition); 2287 Bits = (Bits << 1) | unsigned(II->isExtensionToken()); 2288 Bits = (Bits << 1) | unsigned(II->isPoisoned()); 2289 Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier()); 2290 Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword()); 2291 clang::io::Emit16(Out, Bits); 2292 2293 if (hasMacroDefinition) 2294 clang::io::Emit32(Out, Writer.getMacroOffset(II)); 2295 2296 // Emit the declaration IDs in reverse order, because the 2297 // IdentifierResolver provides the declarations as they would be 2298 // visible (e.g., the function "stat" would come before the struct 2299 // "stat"), but IdentifierResolver::AddDeclToIdentifierChain() 2300 // adds declarations to the end of the list (so we need to see the 2301 // struct "status" before the function "status"). 2302 // Only emit declarations that aren't from a chained PCH, though. 2303 llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II), 2304 IdentifierResolver::end()); 2305 for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(), 2306 DEnd = Decls.rend(); 2307 D != DEnd; ++D) 2308 clang::io::Emit32(Out, Writer.getDeclID(*D)); 2309 } 2310}; 2311} // end anonymous namespace 2312 2313/// \brief Write the identifier table into the AST file. 2314/// 2315/// The identifier table consists of a blob containing string data 2316/// (the actual identifiers themselves) and a separate "offsets" index 2317/// that maps identifier IDs to locations within the blob. 2318void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { 2319 using namespace llvm; 2320 2321 // Create and write out the blob that contains the identifier 2322 // strings. 2323 { 2324 OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; 2325 ASTIdentifierTableTrait Trait(*this, PP); 2326 2327 // Look for any identifiers that were named while processing the 2328 // headers, but are otherwise not needed. We add these to the hash 2329 // table to enable checking of the predefines buffer in the case 2330 // where the user adds new macro definitions when building the AST 2331 // file. 2332 for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(), 2333 IDEnd = PP.getIdentifierTable().end(); 2334 ID != IDEnd; ++ID) 2335 getIdentifierRef(ID->second); 2336 2337 // Create the on-disk hash table representation. We only store offsets 2338 // for identifiers that appear here for the first time. 2339 IdentifierOffsets.resize(NextIdentID - FirstIdentID); 2340 for (llvm::DenseMap<const IdentifierInfo *, IdentID>::iterator 2341 ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end(); 2342 ID != IDEnd; ++ID) { 2343 assert(ID->first && "NULL identifier in identifier table"); 2344 if (!Chain || !ID->first->isFromAST()) 2345 Generator.insert(ID->first, ID->second, Trait); 2346 } 2347 2348 // Create the on-disk hash table in a buffer. 2349 llvm::SmallString<4096> IdentifierTable; 2350 uint32_t BucketOffset; 2351 { 2352 ASTIdentifierTableTrait Trait(*this, PP); 2353 llvm::raw_svector_ostream Out(IdentifierTable); 2354 // Make sure that no bucket is at offset 0 2355 clang::io::Emit32(Out, 0); 2356 BucketOffset = Generator.Emit(Out, Trait); 2357 } 2358 2359 // Create a blob abbreviation 2360 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 2361 Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE)); 2362 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 2363 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2364 unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev); 2365 2366 // Write the identifier table 2367 RecordData Record; 2368 Record.push_back(IDENTIFIER_TABLE); 2369 Record.push_back(BucketOffset); 2370 Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str()); 2371 } 2372 2373 // Write the offsets table for identifier IDs. 2374 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 2375 Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET)); 2376 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers 2377 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2378 unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 2379 2380 RecordData Record; 2381 Record.push_back(IDENTIFIER_OFFSET); 2382 Record.push_back(IdentifierOffsets.size()); 2383 Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, 2384 data(IdentifierOffsets)); 2385} 2386 2387//===----------------------------------------------------------------------===// 2388// DeclContext's Name Lookup Table Serialization 2389//===----------------------------------------------------------------------===// 2390 2391namespace { 2392// Trait used for the on-disk hash table used in the method pool. 2393class ASTDeclContextNameLookupTrait { 2394 ASTWriter &Writer; 2395 2396public: 2397 typedef DeclarationName key_type; 2398 typedef key_type key_type_ref; 2399 2400 typedef DeclContext::lookup_result data_type; 2401 typedef const data_type& data_type_ref; 2402 2403 explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { } 2404 2405 unsigned ComputeHash(DeclarationName Name) { 2406 llvm::FoldingSetNodeID ID; 2407 ID.AddInteger(Name.getNameKind()); 2408 2409 switch (Name.getNameKind()) { 2410 case DeclarationName::Identifier: 2411 ID.AddString(Name.getAsIdentifierInfo()->getName()); 2412 break; 2413 case DeclarationName::ObjCZeroArgSelector: 2414 case DeclarationName::ObjCOneArgSelector: 2415 case DeclarationName::ObjCMultiArgSelector: 2416 ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector())); 2417 break; 2418 case DeclarationName::CXXConstructorName: 2419 case DeclarationName::CXXDestructorName: 2420 case DeclarationName::CXXConversionFunctionName: 2421 ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType())); 2422 break; 2423 case DeclarationName::CXXOperatorName: 2424 ID.AddInteger(Name.getCXXOverloadedOperator()); 2425 break; 2426 case DeclarationName::CXXLiteralOperatorName: 2427 ID.AddString(Name.getCXXLiteralIdentifier()->getName()); 2428 case DeclarationName::CXXUsingDirective: 2429 break; 2430 } 2431 2432 return ID.ComputeHash(); 2433 } 2434 2435 std::pair<unsigned,unsigned> 2436 EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name, 2437 data_type_ref Lookup) { 2438 unsigned KeyLen = 1; 2439 switch (Name.getNameKind()) { 2440 case DeclarationName::Identifier: 2441 case DeclarationName::ObjCZeroArgSelector: 2442 case DeclarationName::ObjCOneArgSelector: 2443 case DeclarationName::ObjCMultiArgSelector: 2444 case DeclarationName::CXXConstructorName: 2445 case DeclarationName::CXXDestructorName: 2446 case DeclarationName::CXXConversionFunctionName: 2447 case DeclarationName::CXXLiteralOperatorName: 2448 KeyLen += 4; 2449 break; 2450 case DeclarationName::CXXOperatorName: 2451 KeyLen += 1; 2452 break; 2453 case DeclarationName::CXXUsingDirective: 2454 break; 2455 } 2456 clang::io::Emit16(Out, KeyLen); 2457 2458 // 2 bytes for num of decls and 4 for each DeclID. 2459 unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first); 2460 clang::io::Emit16(Out, DataLen); 2461 2462 return std::make_pair(KeyLen, DataLen); 2463 } 2464 2465 void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) { 2466 using namespace clang::io; 2467 2468 assert(Name.getNameKind() < 0x100 && "Invalid name kind ?"); 2469 Emit8(Out, Name.getNameKind()); 2470 switch (Name.getNameKind()) { 2471 case DeclarationName::Identifier: 2472 Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo())); 2473 break; 2474 case DeclarationName::ObjCZeroArgSelector: 2475 case DeclarationName::ObjCOneArgSelector: 2476 case DeclarationName::ObjCMultiArgSelector: 2477 Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector())); 2478 break; 2479 case DeclarationName::CXXConstructorName: 2480 case DeclarationName::CXXDestructorName: 2481 case DeclarationName::CXXConversionFunctionName: 2482 Emit32(Out, Writer.getTypeID(Name.getCXXNameType())); 2483 break; 2484 case DeclarationName::CXXOperatorName: 2485 assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?"); 2486 Emit8(Out, Name.getCXXOverloadedOperator()); 2487 break; 2488 case DeclarationName::CXXLiteralOperatorName: 2489 Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier())); 2490 break; 2491 case DeclarationName::CXXUsingDirective: 2492 break; 2493 } 2494 } 2495 2496 void EmitData(llvm::raw_ostream& Out, key_type_ref, 2497 data_type Lookup, unsigned DataLen) { 2498 uint64_t Start = Out.tell(); (void)Start; 2499 clang::io::Emit16(Out, Lookup.second - Lookup.first); 2500 for (; Lookup.first != Lookup.second; ++Lookup.first) 2501 clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first)); 2502 2503 assert(Out.tell() - Start == DataLen && "Data length is wrong"); 2504 } 2505}; 2506} // end anonymous namespace 2507 2508/// \brief Write the block containing all of the declaration IDs 2509/// visible from the given DeclContext. 2510/// 2511/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the 2512/// bitstream, or 0 if no block was written. 2513uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, 2514 DeclContext *DC) { 2515 if (DC->getPrimaryContext() != DC) 2516 return 0; 2517 2518 // Since there is no name lookup into functions or methods, don't bother to 2519 // build a visible-declarations table for these entities. 2520 if (DC->isFunctionOrMethod()) 2521 return 0; 2522 2523 // If not in C++, we perform name lookup for the translation unit via the 2524 // IdentifierInfo chains, don't bother to build a visible-declarations table. 2525 // FIXME: In C++ we need the visible declarations in order to "see" the 2526 // friend declarations, is there a way to do this without writing the table ? 2527 if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) 2528 return 0; 2529 2530 // Force the DeclContext to build a its name-lookup table. 2531 if (DC->hasExternalVisibleStorage()) 2532 DC->MaterializeVisibleDeclsFromExternalStorage(); 2533 else 2534 DC->lookup(DeclarationName()); 2535 2536 // Serialize the contents of the mapping used for lookup. Note that, 2537 // although we have two very different code paths, the serialized 2538 // representation is the same for both cases: a declaration name, 2539 // followed by a size, followed by references to the visible 2540 // declarations that have that name. 2541 uint64_t Offset = Stream.GetCurrentBitNo(); 2542 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); 2543 if (!Map || Map->empty()) 2544 return 0; 2545 2546 OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; 2547 ASTDeclContextNameLookupTrait Trait(*this); 2548 2549 // Create the on-disk hash table representation. 2550 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); 2551 D != DEnd; ++D) { 2552 DeclarationName Name = D->first; 2553 DeclContext::lookup_result Result = D->second.getLookupResult(); 2554 Generator.insert(Name, Result, Trait); 2555 } 2556 2557 // Create the on-disk hash table in a buffer. 2558 llvm::SmallString<4096> LookupTable; 2559 uint32_t BucketOffset; 2560 { 2561 llvm::raw_svector_ostream Out(LookupTable); 2562 // Make sure that no bucket is at offset 0 2563 clang::io::Emit32(Out, 0); 2564 BucketOffset = Generator.Emit(Out, Trait); 2565 } 2566 2567 // Write the lookup table 2568 RecordData Record; 2569 Record.push_back(DECL_CONTEXT_VISIBLE); 2570 Record.push_back(BucketOffset); 2571 Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, 2572 LookupTable.str()); 2573 2574 Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); 2575 ++NumVisibleDeclContexts; 2576 return Offset; 2577} 2578 2579/// \brief Write an UPDATE_VISIBLE block for the given context. 2580/// 2581/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing 2582/// DeclContext in a dependent AST file. As such, they only exist for the TU 2583/// (in C++) and for namespaces. 2584void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { 2585 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); 2586 if (!Map || Map->empty()) 2587 return; 2588 2589 OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; 2590 ASTDeclContextNameLookupTrait Trait(*this); 2591 2592 // Create the hash table. 2593 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); 2594 D != DEnd; ++D) { 2595 DeclarationName Name = D->first; 2596 DeclContext::lookup_result Result = D->second.getLookupResult(); 2597 // For any name that appears in this table, the results are complete, i.e. 2598 // they overwrite results from previous PCHs. Merging is always a mess. 2599 Generator.insert(Name, Result, Trait); 2600 } 2601 2602 // Create the on-disk hash table in a buffer. 2603 llvm::SmallString<4096> LookupTable; 2604 uint32_t BucketOffset; 2605 { 2606 llvm::raw_svector_ostream Out(LookupTable); 2607 // Make sure that no bucket is at offset 0 2608 clang::io::Emit32(Out, 0); 2609 BucketOffset = Generator.Emit(Out, Trait); 2610 } 2611 2612 // Write the lookup table 2613 RecordData Record; 2614 Record.push_back(UPDATE_VISIBLE); 2615 Record.push_back(getDeclID(cast<Decl>(DC))); 2616 Record.push_back(BucketOffset); 2617 Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); 2618} 2619 2620/// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions. 2621void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) { 2622 RecordData Record; 2623 Record.push_back(Opts.fp_contract); 2624 Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record); 2625} 2626 2627/// \brief Write an OPENCL_EXTENSIONS block for the given OpenCLOptions. 2628void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { 2629 if (!SemaRef.Context.getLangOptions().OpenCL) 2630 return; 2631 2632 const OpenCLOptions &Opts = SemaRef.getOpenCLOptions(); 2633 RecordData Record; 2634#define OPENCLEXT(nm) Record.push_back(Opts.nm); 2635#include "clang/Basic/OpenCLExtensions.def" 2636 Stream.EmitRecord(OPENCL_EXTENSIONS, Record); 2637} 2638 2639//===----------------------------------------------------------------------===// 2640// General Serialization Routines 2641//===----------------------------------------------------------------------===// 2642 2643/// \brief Write a record containing the given attributes. 2644void ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) { 2645 Record.push_back(Attrs.size()); 2646 for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){ 2647 const Attr * A = *i; 2648 Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs 2649 AddSourceLocation(A->getLocation(), Record); 2650 2651#include "clang/Serialization/AttrPCHWrite.inc" 2652 2653 } 2654} 2655 2656void ASTWriter::AddString(llvm::StringRef Str, RecordDataImpl &Record) { 2657 Record.push_back(Str.size()); 2658 Record.insert(Record.end(), Str.begin(), Str.end()); 2659} 2660 2661void ASTWriter::AddVersionTuple(const VersionTuple &Version, 2662 RecordDataImpl &Record) { 2663 Record.push_back(Version.getMajor()); 2664 if (llvm::Optional<unsigned> Minor = Version.getMinor()) 2665 Record.push_back(*Minor + 1); 2666 else 2667 Record.push_back(0); 2668 if (llvm::Optional<unsigned> Subminor = Version.getSubminor()) 2669 Record.push_back(*Subminor + 1); 2670 else 2671 Record.push_back(0); 2672} 2673 2674/// \brief Note that the identifier II occurs at the given offset 2675/// within the identifier table. 2676void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { 2677 IdentID ID = IdentifierIDs[II]; 2678 // Only store offsets new to this AST file. Other identifier names are looked 2679 // up earlier in the chain and thus don't need an offset. 2680 if (ID >= FirstIdentID) 2681 IdentifierOffsets[ID - FirstIdentID] = Offset; 2682} 2683 2684/// \brief Note that the selector Sel occurs at the given offset 2685/// within the method pool/selector table. 2686void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { 2687 unsigned ID = SelectorIDs[Sel]; 2688 assert(ID && "Unknown selector"); 2689 // Don't record offsets for selectors that are also available in a different 2690 // file. 2691 if (ID < FirstSelectorID) 2692 return; 2693 SelectorOffsets[ID - FirstSelectorID] = Offset; 2694} 2695 2696ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) 2697 : Stream(Stream), Chain(0), SerializationListener(0), 2698 FirstDeclID(1), NextDeclID(FirstDeclID), 2699 FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), 2700 FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), 2701 NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID), 2702 CollectedStmts(&StmtsToEmit), 2703 NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), 2704 NumVisibleDeclContexts(0), 2705 FirstCXXBaseSpecifiersID(1), NextCXXBaseSpecifiersID(1), 2706 DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0), 2707 DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0), 2708 DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0), 2709 DeclRecordAbbrev(0), IntegerLiteralAbbrev(0), 2710 DeclTypedefAbbrev(0), 2711 DeclVarAbbrev(0), DeclFieldAbbrev(0), 2712 DeclEnumAbbrev(0), DeclObjCIvarAbbrev(0) 2713{ 2714} 2715 2716void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2717 const std::string &OutputFile, 2718 const char *isysroot) { 2719 // Emit the file header. 2720 Stream.Emit((unsigned)'C', 8); 2721 Stream.Emit((unsigned)'P', 8); 2722 Stream.Emit((unsigned)'C', 8); 2723 Stream.Emit((unsigned)'H', 8); 2724 2725 WriteBlockInfoBlock(); 2726 2727 if (Chain) 2728 WriteASTChain(SemaRef, StatCalls, isysroot); 2729 else 2730 WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile); 2731} 2732 2733void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2734 const char *isysroot, 2735 const std::string &OutputFile) { 2736 using namespace llvm; 2737 2738 ASTContext &Context = SemaRef.Context; 2739 Preprocessor &PP = SemaRef.PP; 2740 2741 // The translation unit is the first declaration we'll emit. 2742 DeclIDs[Context.getTranslationUnitDecl()] = 1; 2743 ++NextDeclID; 2744 DeclTypesToEmit.push(Context.getTranslationUnitDecl()); 2745 2746 // Make sure that we emit IdentifierInfos (and any attached 2747 // declarations) for builtins. 2748 { 2749 IdentifierTable &Table = PP.getIdentifierTable(); 2750 llvm::SmallVector<const char *, 32> BuiltinNames; 2751 Context.BuiltinInfo.GetBuiltinNames(BuiltinNames, 2752 Context.getLangOptions().NoBuiltin); 2753 for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I) 2754 getIdentifierRef(&Table.get(BuiltinNames[I])); 2755 } 2756 2757 // Build a record containing all of the tentative definitions in this file, in 2758 // TentativeDefinitions order. Generally, this record will be empty for 2759 // headers. 2760 RecordData TentativeDefinitions; 2761 for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 2762 AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 2763 } 2764 2765 // Build a record containing all of the file scoped decls in this file. 2766 RecordData UnusedFileScopedDecls; 2767 for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) 2768 AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 2769 2770 RecordData DelegatingCtorDecls; 2771 for (unsigned i=0, e = SemaRef.DelegatingCtorDecls.size(); i != e; ++i) 2772 AddDeclRef(SemaRef.DelegatingCtorDecls[i], DelegatingCtorDecls); 2773 2774 RecordData WeakUndeclaredIdentifiers; 2775 if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 2776 WeakUndeclaredIdentifiers.push_back( 2777 SemaRef.WeakUndeclaredIdentifiers.size()); 2778 for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 2779 I = SemaRef.WeakUndeclaredIdentifiers.begin(), 2780 E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 2781 AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 2782 AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 2783 AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 2784 WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 2785 } 2786 } 2787 2788 // Build a record containing all of the locally-scoped external 2789 // declarations in this header file. Generally, this record will be 2790 // empty. 2791 RecordData LocallyScopedExternalDecls; 2792 // FIXME: This is filling in the AST file in densemap order which is 2793 // nondeterminstic! 2794 for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 2795 TD = SemaRef.LocallyScopedExternalDecls.begin(), 2796 TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 2797 TD != TDEnd; ++TD) 2798 AddDeclRef(TD->second, LocallyScopedExternalDecls); 2799 2800 // Build a record containing all of the ext_vector declarations. 2801 RecordData ExtVectorDecls; 2802 for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) 2803 AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 2804 2805 // Build a record containing all of the VTable uses information. 2806 RecordData VTableUses; 2807 if (!SemaRef.VTableUses.empty()) { 2808 VTableUses.push_back(SemaRef.VTableUses.size()); 2809 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 2810 AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 2811 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 2812 VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 2813 } 2814 } 2815 2816 // Build a record containing all of dynamic classes declarations. 2817 RecordData DynamicClasses; 2818 for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 2819 AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 2820 2821 // Build a record containing all of pending implicit instantiations. 2822 RecordData PendingInstantiations; 2823 for (std::deque<Sema::PendingImplicitInstantiation>::iterator 2824 I = SemaRef.PendingInstantiations.begin(), 2825 N = SemaRef.PendingInstantiations.end(); I != N; ++I) { 2826 AddDeclRef(I->first, PendingInstantiations); 2827 AddSourceLocation(I->second, PendingInstantiations); 2828 } 2829 assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 2830 "There are local ones at end of translation unit!"); 2831 2832 // Build a record containing some declaration references. 2833 RecordData SemaDeclRefs; 2834 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 2835 AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 2836 AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 2837 } 2838 2839 RecordData CUDASpecialDeclRefs; 2840 if (Context.getcudaConfigureCallDecl()) { 2841 AddDeclRef(Context.getcudaConfigureCallDecl(), CUDASpecialDeclRefs); 2842 } 2843 2844 // Write the remaining AST contents. 2845 RecordData Record; 2846 Stream.EnterSubblock(AST_BLOCK_ID, 5); 2847 WriteMetadata(Context, isysroot, OutputFile); 2848 WriteLanguageOptions(Context.getLangOptions()); 2849 if (StatCalls && !isysroot) 2850 WriteStatCache(*StatCalls); 2851 WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2852 // Write the record of special types. 2853 Record.clear(); 2854 2855 AddTypeRef(Context.getBuiltinVaListType(), Record); 2856 AddTypeRef(Context.getObjCIdType(), Record); 2857 AddTypeRef(Context.getObjCSelType(), Record); 2858 AddTypeRef(Context.getObjCProtoType(), Record); 2859 AddTypeRef(Context.getObjCClassType(), Record); 2860 AddTypeRef(Context.getRawCFConstantStringType(), Record); 2861 AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record); 2862 AddTypeRef(Context.getFILEType(), Record); 2863 AddTypeRef(Context.getjmp_bufType(), Record); 2864 AddTypeRef(Context.getsigjmp_bufType(), Record); 2865 AddTypeRef(Context.ObjCIdRedefinitionType, Record); 2866 AddTypeRef(Context.ObjCClassRedefinitionType, Record); 2867 AddTypeRef(Context.getRawBlockdescriptorType(), Record); 2868 AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record); 2869 AddTypeRef(Context.ObjCSelRedefinitionType, Record); 2870 AddTypeRef(Context.getRawNSConstantStringType(), Record); 2871 Record.push_back(Context.isInt128Installed()); 2872 AddTypeRef(Context.AutoDeductTy, Record); 2873 AddTypeRef(Context.AutoRRefDeductTy, Record); 2874 Stream.EmitRecord(SPECIAL_TYPES, Record); 2875 2876 // Keep writing types and declarations until all types and 2877 // declarations have been written. 2878 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE); 2879 WriteDeclsBlockAbbrevs(); 2880 while (!DeclTypesToEmit.empty()) { 2881 DeclOrType DOT = DeclTypesToEmit.front(); 2882 DeclTypesToEmit.pop(); 2883 if (DOT.isType()) 2884 WriteType(DOT.getType()); 2885 else 2886 WriteDecl(Context, DOT.getDecl()); 2887 } 2888 Stream.ExitBlock(); 2889 2890 WritePreprocessor(PP); 2891 WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot); 2892 WriteSelectors(SemaRef); 2893 WriteReferencedSelectorsPool(SemaRef); 2894 WriteIdentifierTable(PP); 2895 WriteFPPragmaOptions(SemaRef.getFPOptions()); 2896 WriteOpenCLExtensions(SemaRef); 2897 2898 WriteTypeDeclOffsets(); 2899 WritePragmaDiagnosticMappings(Context.getDiagnostics()); 2900 2901 WriteCXXBaseSpecifiersOffsets(); 2902 2903 // Write the record containing external, unnamed definitions. 2904 if (!ExternalDefinitions.empty()) 2905 Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 2906 2907 // Write the record containing tentative definitions. 2908 if (!TentativeDefinitions.empty()) 2909 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 2910 2911 // Write the record containing unused file scoped decls. 2912 if (!UnusedFileScopedDecls.empty()) 2913 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 2914 2915 // Write the record containing weak undeclared identifiers. 2916 if (!WeakUndeclaredIdentifiers.empty()) 2917 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 2918 WeakUndeclaredIdentifiers); 2919 2920 // Write the record containing locally-scoped external definitions. 2921 if (!LocallyScopedExternalDecls.empty()) 2922 Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 2923 LocallyScopedExternalDecls); 2924 2925 // Write the record containing ext_vector type names. 2926 if (!ExtVectorDecls.empty()) 2927 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 2928 2929 // Write the record containing VTable uses information. 2930 if (!VTableUses.empty()) 2931 Stream.EmitRecord(VTABLE_USES, VTableUses); 2932 2933 // Write the record containing dynamic classes declarations. 2934 if (!DynamicClasses.empty()) 2935 Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 2936 2937 // Write the record containing pending implicit instantiations. 2938 if (!PendingInstantiations.empty()) 2939 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); 2940 2941 // Write the record containing declaration references of Sema. 2942 if (!SemaDeclRefs.empty()) 2943 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 2944 2945 // Write the record containing CUDA-specific declaration references. 2946 if (!CUDASpecialDeclRefs.empty()) 2947 Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs); 2948 2949 // Write the delegating constructors. 2950 if (!DelegatingCtorDecls.empty()) 2951 Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls); 2952 2953 // Some simple statistics 2954 Record.clear(); 2955 Record.push_back(NumStatements); 2956 Record.push_back(NumMacros); 2957 Record.push_back(NumLexicalDeclContexts); 2958 Record.push_back(NumVisibleDeclContexts); 2959 Stream.EmitRecord(STATISTICS, Record); 2960 Stream.ExitBlock(); 2961} 2962 2963void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2964 const char *isysroot) { 2965 using namespace llvm; 2966 2967 ASTContext &Context = SemaRef.Context; 2968 Preprocessor &PP = SemaRef.PP; 2969 2970 RecordData Record; 2971 Stream.EnterSubblock(AST_BLOCK_ID, 5); 2972 WriteMetadata(Context, isysroot, ""); 2973 if (StatCalls && !isysroot) 2974 WriteStatCache(*StatCalls); 2975 // FIXME: Source manager block should only write new stuff, which could be 2976 // done by tracking the largest ID in the chain 2977 WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2978 2979 // The special types are in the chained PCH. 2980 2981 // We don't start with the translation unit, but with its decls that 2982 // don't come from the chained PCH. 2983 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); 2984 llvm::SmallVector<KindDeclIDPair, 64> NewGlobalDecls; 2985 for (DeclContext::decl_iterator I = TU->noload_decls_begin(), 2986 E = TU->noload_decls_end(); 2987 I != E; ++I) { 2988 if ((*I)->getPCHLevel() == 0) 2989 NewGlobalDecls.push_back(std::make_pair((*I)->getKind(), GetDeclRef(*I))); 2990 else if ((*I)->isChangedSinceDeserialization()) 2991 (void)GetDeclRef(*I); // Make sure it's written, but don't record it. 2992 } 2993 // We also need to write a lexical updates block for the TU. 2994 llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev(); 2995 Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); 2996 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 2997 unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abv); 2998 Record.clear(); 2999 Record.push_back(TU_UPDATE_LEXICAL); 3000 Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, 3001 data(NewGlobalDecls)); 3002 // And a visible updates block for the DeclContexts. 3003 Abv = new llvm::BitCodeAbbrev(); 3004 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); 3005 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 3006 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); 3007 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 3008 UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); 3009 WriteDeclContextVisibleUpdate(TU); 3010 3011 // Build a record containing all of the new tentative definitions in this 3012 // file, in TentativeDefinitions order. 3013 RecordData TentativeDefinitions; 3014 for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 3015 if (SemaRef.TentativeDefinitions[i]->getPCHLevel() == 0) 3016 AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 3017 } 3018 3019 // Build a record containing all of the file scoped decls in this file. 3020 RecordData UnusedFileScopedDecls; 3021 for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) { 3022 if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0) 3023 AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 3024 } 3025 3026 // Build a record containing all of the delegating constructor decls in this 3027 // file. 3028 RecordData DelegatingCtorDecls; 3029 for (unsigned i=0, e = SemaRef.DelegatingCtorDecls.size(); i != e; ++i) { 3030 if (SemaRef.DelegatingCtorDecls[i]->getPCHLevel() == 0) 3031 AddDeclRef(SemaRef.DelegatingCtorDecls[i], DelegatingCtorDecls); 3032 } 3033 3034 // We write the entire table, overwriting the tables from the chain. 3035 RecordData WeakUndeclaredIdentifiers; 3036 if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 3037 WeakUndeclaredIdentifiers.push_back( 3038 SemaRef.WeakUndeclaredIdentifiers.size()); 3039 for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 3040 I = SemaRef.WeakUndeclaredIdentifiers.begin(), 3041 E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 3042 AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 3043 AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 3044 AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 3045 WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 3046 } 3047 } 3048 3049 // Build a record containing all of the locally-scoped external 3050 // declarations in this header file. Generally, this record will be 3051 // empty. 3052 RecordData LocallyScopedExternalDecls; 3053 // FIXME: This is filling in the AST file in densemap order which is 3054 // nondeterminstic! 3055 for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 3056 TD = SemaRef.LocallyScopedExternalDecls.begin(), 3057 TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 3058 TD != TDEnd; ++TD) { 3059 if (TD->second->getPCHLevel() == 0) 3060 AddDeclRef(TD->second, LocallyScopedExternalDecls); 3061 } 3062 3063 // Build a record containing all of the ext_vector declarations. 3064 RecordData ExtVectorDecls; 3065 for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) { 3066 if (SemaRef.ExtVectorDecls[I]->getPCHLevel() == 0) 3067 AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 3068 } 3069 3070 // Build a record containing all of the VTable uses information. 3071 // We write everything here, because it's too hard to determine whether 3072 // a use is new to this part. 3073 RecordData VTableUses; 3074 if (!SemaRef.VTableUses.empty()) { 3075 VTableUses.push_back(SemaRef.VTableUses.size()); 3076 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 3077 AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 3078 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 3079 VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 3080 } 3081 } 3082 3083 // Build a record containing all of dynamic classes declarations. 3084 RecordData DynamicClasses; 3085 for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 3086 if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0) 3087 AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 3088 3089 // Build a record containing all of pending implicit instantiations. 3090 RecordData PendingInstantiations; 3091 for (std::deque<Sema::PendingImplicitInstantiation>::iterator 3092 I = SemaRef.PendingInstantiations.begin(), 3093 N = SemaRef.PendingInstantiations.end(); I != N; ++I) { 3094 AddDeclRef(I->first, PendingInstantiations); 3095 AddSourceLocation(I->second, PendingInstantiations); 3096 } 3097 assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 3098 "There are local ones at end of translation unit!"); 3099 3100 // Build a record containing some declaration references. 3101 // It's not worth the effort to avoid duplication here. 3102 RecordData SemaDeclRefs; 3103 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 3104 AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 3105 AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 3106 } 3107 3108 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE); 3109 WriteDeclsBlockAbbrevs(); 3110 for (DeclsToRewriteTy::iterator 3111 I = DeclsToRewrite.begin(), E = DeclsToRewrite.end(); I != E; ++I) 3112 DeclTypesToEmit.push(const_cast<Decl*>(*I)); 3113 while (!DeclTypesToEmit.empty()) { 3114 DeclOrType DOT = DeclTypesToEmit.front(); 3115 DeclTypesToEmit.pop(); 3116 if (DOT.isType()) 3117 WriteType(DOT.getType()); 3118 else 3119 WriteDecl(Context, DOT.getDecl()); 3120 } 3121 Stream.ExitBlock(); 3122 3123 WritePreprocessor(PP); 3124 WriteSelectors(SemaRef); 3125 WriteReferencedSelectorsPool(SemaRef); 3126 WriteIdentifierTable(PP); 3127 WriteFPPragmaOptions(SemaRef.getFPOptions()); 3128 WriteOpenCLExtensions(SemaRef); 3129 3130 WriteTypeDeclOffsets(); 3131 // FIXME: For chained PCH only write the new mappings (we currently 3132 // write all of them again). 3133 WritePragmaDiagnosticMappings(Context.getDiagnostics()); 3134 3135 WriteCXXBaseSpecifiersOffsets(); 3136 3137 /// Build a record containing first declarations from a chained PCH and the 3138 /// most recent declarations in this AST that they point to. 3139 RecordData FirstLatestDeclIDs; 3140 for (FirstLatestDeclMap::iterator 3141 I = FirstLatestDecls.begin(), E = FirstLatestDecls.end(); I != E; ++I) { 3142 assert(I->first->getPCHLevel() > I->second->getPCHLevel() && 3143 "Expected first & second to be in different PCHs"); 3144 AddDeclRef(I->first, FirstLatestDeclIDs); 3145 AddDeclRef(I->second, FirstLatestDeclIDs); 3146 } 3147 if (!FirstLatestDeclIDs.empty()) 3148 Stream.EmitRecord(REDECLS_UPDATE_LATEST, FirstLatestDeclIDs); 3149 3150 // Write the record containing external, unnamed definitions. 3151 if (!ExternalDefinitions.empty()) 3152 Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 3153 3154 // Write the record containing tentative definitions. 3155 if (!TentativeDefinitions.empty()) 3156 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 3157 3158 // Write the record containing unused file scoped decls. 3159 if (!UnusedFileScopedDecls.empty()) 3160 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 3161 3162 // Write the record containing weak undeclared identifiers. 3163 if (!WeakUndeclaredIdentifiers.empty()) 3164 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 3165 WeakUndeclaredIdentifiers); 3166 3167 // Write the record containing locally-scoped external definitions. 3168 if (!LocallyScopedExternalDecls.empty()) 3169 Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 3170 LocallyScopedExternalDecls); 3171 3172 // Write the record containing ext_vector type names. 3173 if (!ExtVectorDecls.empty()) 3174 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 3175 3176 // Write the record containing VTable uses information. 3177 if (!VTableUses.empty()) 3178 Stream.EmitRecord(VTABLE_USES, VTableUses); 3179 3180 // Write the record containing dynamic classes declarations. 3181 if (!DynamicClasses.empty()) 3182 Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 3183 3184 // Write the record containing pending implicit instantiations. 3185 if (!PendingInstantiations.empty()) 3186 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); 3187 3188 // Write the record containing declaration references of Sema. 3189 if (!SemaDeclRefs.empty()) 3190 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 3191 3192 // Write the delegating constructors. 3193 if (!DelegatingCtorDecls.empty()) 3194 Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls); 3195 3196 // Write the updates to DeclContexts. 3197 for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator 3198 I = UpdatedDeclContexts.begin(), 3199 E = UpdatedDeclContexts.end(); 3200 I != E; ++I) 3201 WriteDeclContextVisibleUpdate(*I); 3202 3203 WriteDeclUpdatesBlocks(); 3204 3205 Record.clear(); 3206 Record.push_back(NumStatements); 3207 Record.push_back(NumMacros); 3208 Record.push_back(NumLexicalDeclContexts); 3209 Record.push_back(NumVisibleDeclContexts); 3210 WriteDeclReplacementsBlock(); 3211 Stream.EmitRecord(STATISTICS, Record); 3212 Stream.ExitBlock(); 3213} 3214 3215void ASTWriter::WriteDeclUpdatesBlocks() { 3216 if (DeclUpdates.empty()) 3217 return; 3218 3219 RecordData OffsetsRecord; 3220 Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE); 3221 for (DeclUpdateMap::iterator 3222 I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) { 3223 const Decl *D = I->first; 3224 UpdateRecord &URec = I->second; 3225 3226 if (DeclsToRewrite.count(D)) 3227 continue; // The decl will be written completely,no need to store updates. 3228 3229 uint64_t Offset = Stream.GetCurrentBitNo(); 3230 Stream.EmitRecord(DECL_UPDATES, URec); 3231 3232 OffsetsRecord.push_back(GetDeclRef(D)); 3233 OffsetsRecord.push_back(Offset); 3234 } 3235 Stream.ExitBlock(); 3236 Stream.EmitRecord(DECL_UPDATE_OFFSETS, OffsetsRecord); 3237} 3238 3239void ASTWriter::WriteDeclReplacementsBlock() { 3240 if (ReplacedDecls.empty()) 3241 return; 3242 3243 RecordData Record; 3244 for (llvm::SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator 3245 I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) { 3246 Record.push_back(I->first); 3247 Record.push_back(I->second); 3248 } 3249 Stream.EmitRecord(DECL_REPLACEMENTS, Record); 3250} 3251 3252void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) { 3253 Record.push_back(Loc.getRawEncoding()); 3254} 3255 3256void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) { 3257 AddSourceLocation(Range.getBegin(), Record); 3258 AddSourceLocation(Range.getEnd(), Record); 3259} 3260 3261void ASTWriter::AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record) { 3262 Record.push_back(Value.getBitWidth()); 3263 const uint64_t *Words = Value.getRawData(); 3264 Record.append(Words, Words + Value.getNumWords()); 3265} 3266 3267void ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record) { 3268 Record.push_back(Value.isUnsigned()); 3269 AddAPInt(Value, Record); 3270} 3271 3272void ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record) { 3273 AddAPInt(Value.bitcastToAPInt(), Record); 3274} 3275 3276void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) { 3277 Record.push_back(getIdentifierRef(II)); 3278} 3279 3280IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) { 3281 if (II == 0) 3282 return 0; 3283 3284 IdentID &ID = IdentifierIDs[II]; 3285 if (ID == 0) 3286 ID = NextIdentID++; 3287 return ID; 3288} 3289 3290MacroID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) { 3291 if (MD == 0) 3292 return 0; 3293 3294 MacroID &ID = MacroDefinitions[MD]; 3295 if (ID == 0) 3296 ID = NextMacroID++; 3297 return ID; 3298} 3299 3300void ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) { 3301 Record.push_back(getSelectorRef(SelRef)); 3302} 3303 3304SelectorID ASTWriter::getSelectorRef(Selector Sel) { 3305 if (Sel.getAsOpaquePtr() == 0) { 3306 return 0; 3307 } 3308 3309 SelectorID &SID = SelectorIDs[Sel]; 3310 if (SID == 0 && Chain) { 3311 // This might trigger a ReadSelector callback, which will set the ID for 3312 // this selector. 3313 Chain->LoadSelector(Sel); 3314 } 3315 if (SID == 0) { 3316 SID = NextSelectorID++; 3317 } 3318 return SID; 3319} 3320 3321void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record) { 3322 AddDeclRef(Temp->getDestructor(), Record); 3323} 3324 3325void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, 3326 CXXBaseSpecifier const *BasesEnd, 3327 RecordDataImpl &Record) { 3328 assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded"); 3329 CXXBaseSpecifiersToWrite.push_back( 3330 QueuedCXXBaseSpecifiers(NextCXXBaseSpecifiersID, 3331 Bases, BasesEnd)); 3332 Record.push_back(NextCXXBaseSpecifiersID++); 3333} 3334 3335void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, 3336 const TemplateArgumentLocInfo &Arg, 3337 RecordDataImpl &Record) { 3338 switch (Kind) { 3339 case TemplateArgument::Expression: 3340 AddStmt(Arg.getAsExpr()); 3341 break; 3342 case TemplateArgument::Type: 3343 AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record); 3344 break; 3345 case TemplateArgument::Template: 3346 AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record); 3347 AddSourceLocation(Arg.getTemplateNameLoc(), Record); 3348 break; 3349 case TemplateArgument::TemplateExpansion: 3350 AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record); 3351 AddSourceLocation(Arg.getTemplateNameLoc(), Record); 3352 AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record); 3353 break; 3354 case TemplateArgument::Null: 3355 case TemplateArgument::Integral: 3356 case TemplateArgument::Declaration: 3357 case TemplateArgument::Pack: 3358 break; 3359 } 3360} 3361 3362void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, 3363 RecordDataImpl &Record) { 3364 AddTemplateArgument(Arg.getArgument(), Record); 3365 3366 if (Arg.getArgument().getKind() == TemplateArgument::Expression) { 3367 bool InfoHasSameExpr 3368 = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr(); 3369 Record.push_back(InfoHasSameExpr); 3370 if (InfoHasSameExpr) 3371 return; // Avoid storing the same expr twice. 3372 } 3373 AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(), 3374 Record); 3375} 3376 3377void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, 3378 RecordDataImpl &Record) { 3379 if (TInfo == 0) { 3380 AddTypeRef(QualType(), Record); 3381 return; 3382 } 3383 3384 AddTypeLoc(TInfo->getTypeLoc(), Record); 3385} 3386 3387void ASTWriter::AddTypeLoc(TypeLoc TL, RecordDataImpl &Record) { 3388 AddTypeRef(TL.getType(), Record); 3389 3390 TypeLocWriter TLW(*this, Record); 3391 for (; !TL.isNull(); TL = TL.getNextTypeLoc()) 3392 TLW.Visit(TL); 3393} 3394 3395void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) { 3396 Record.push_back(GetOrCreateTypeID(T)); 3397} 3398 3399TypeID ASTWriter::GetOrCreateTypeID(QualType T) { 3400 return MakeTypeID(T, 3401 std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this)); 3402} 3403 3404TypeID ASTWriter::getTypeID(QualType T) const { 3405 return MakeTypeID(T, 3406 std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this)); 3407} 3408 3409TypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) { 3410 if (T.isNull()) 3411 return TypeIdx(); 3412 assert(!T.getLocalFastQualifiers()); 3413 3414 TypeIdx &Idx = TypeIdxs[T]; 3415 if (Idx.getIndex() == 0) { 3416 // We haven't seen this type before. Assign it a new ID and put it 3417 // into the queue of types to emit. 3418 Idx = TypeIdx(NextTypeID++); 3419 DeclTypesToEmit.push(T); 3420 } 3421 return Idx; 3422} 3423 3424TypeIdx ASTWriter::getTypeIdx(QualType T) const { 3425 if (T.isNull()) 3426 return TypeIdx(); 3427 assert(!T.getLocalFastQualifiers()); 3428 3429 TypeIdxMap::const_iterator I = TypeIdxs.find(T); 3430 assert(I != TypeIdxs.end() && "Type not emitted!"); 3431 return I->second; 3432} 3433 3434void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { 3435 Record.push_back(GetDeclRef(D)); 3436} 3437 3438DeclID ASTWriter::GetDeclRef(const Decl *D) { 3439 if (D == 0) { 3440 return 0; 3441 } 3442 assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer"); 3443 DeclID &ID = DeclIDs[D]; 3444 if (ID == 0) { 3445 // We haven't seen this declaration before. Give it a new ID and 3446 // enqueue it in the list of declarations to emit. 3447 ID = NextDeclID++; 3448 DeclTypesToEmit.push(const_cast<Decl *>(D)); 3449 } else if (ID < FirstDeclID && D->isChangedSinceDeserialization()) { 3450 // We don't add it to the replacement collection here, because we don't 3451 // have the offset yet. 3452 DeclTypesToEmit.push(const_cast<Decl *>(D)); 3453 // Reset the flag, so that we don't add this decl multiple times. 3454 const_cast<Decl *>(D)->setChangedSinceDeserialization(false); 3455 } 3456 3457 return ID; 3458} 3459 3460DeclID ASTWriter::getDeclID(const Decl *D) { 3461 if (D == 0) 3462 return 0; 3463 3464 assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!"); 3465 return DeclIDs[D]; 3466} 3467 3468void ASTWriter::AddDeclarationName(DeclarationName Name, RecordDataImpl &Record) { 3469 // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc. 3470 Record.push_back(Name.getNameKind()); 3471 switch (Name.getNameKind()) { 3472 case DeclarationName::Identifier: 3473 AddIdentifierRef(Name.getAsIdentifierInfo(), Record); 3474 break; 3475 3476 case DeclarationName::ObjCZeroArgSelector: 3477 case DeclarationName::ObjCOneArgSelector: 3478 case DeclarationName::ObjCMultiArgSelector: 3479 AddSelectorRef(Name.getObjCSelector(), Record); 3480 break; 3481 3482 case DeclarationName::CXXConstructorName: 3483 case DeclarationName::CXXDestructorName: 3484 case DeclarationName::CXXConversionFunctionName: 3485 AddTypeRef(Name.getCXXNameType(), Record); 3486 break; 3487 3488 case DeclarationName::CXXOperatorName: 3489 Record.push_back(Name.getCXXOverloadedOperator()); 3490 break; 3491 3492 case DeclarationName::CXXLiteralOperatorName: 3493 AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record); 3494 break; 3495 3496 case DeclarationName::CXXUsingDirective: 3497 // No extra data to emit 3498 break; 3499 } 3500} 3501 3502void ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, 3503 DeclarationName Name, RecordDataImpl &Record) { 3504 switch (Name.getNameKind()) { 3505 case DeclarationName::CXXConstructorName: 3506 case DeclarationName::CXXDestructorName: 3507 case DeclarationName::CXXConversionFunctionName: 3508 AddTypeSourceInfo(DNLoc.NamedType.TInfo, Record); 3509 break; 3510 3511 case DeclarationName::CXXOperatorName: 3512 AddSourceLocation( 3513 SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.BeginOpNameLoc), 3514 Record); 3515 AddSourceLocation( 3516 SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc), 3517 Record); 3518 break; 3519 3520 case DeclarationName::CXXLiteralOperatorName: 3521 AddSourceLocation( 3522 SourceLocation::getFromRawEncoding(DNLoc.CXXLiteralOperatorName.OpNameLoc), 3523 Record); 3524 break; 3525 3526 case DeclarationName::Identifier: 3527 case DeclarationName::ObjCZeroArgSelector: 3528 case DeclarationName::ObjCOneArgSelector: 3529 case DeclarationName::ObjCMultiArgSelector: 3530 case DeclarationName::CXXUsingDirective: 3531 break; 3532 } 3533} 3534 3535void ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo, 3536 RecordDataImpl &Record) { 3537 AddDeclarationName(NameInfo.getName(), Record); 3538 AddSourceLocation(NameInfo.getLoc(), Record); 3539 AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName(), Record); 3540} 3541 3542void ASTWriter::AddQualifierInfo(const QualifierInfo &Info, 3543 RecordDataImpl &Record) { 3544 AddNestedNameSpecifierLoc(Info.QualifierLoc, Record); 3545 Record.push_back(Info.NumTemplParamLists); 3546 for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i) 3547 AddTemplateParameterList(Info.TemplParamLists[i], Record); 3548} 3549 3550void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, 3551 RecordDataImpl &Record) { 3552 // Nested name specifiers usually aren't too long. I think that 8 would 3553 // typically accommodate the vast majority. 3554 llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames; 3555 3556 // Push each of the NNS's onto a stack for serialization in reverse order. 3557 while (NNS) { 3558 NestedNames.push_back(NNS); 3559 NNS = NNS->getPrefix(); 3560 } 3561 3562 Record.push_back(NestedNames.size()); 3563 while(!NestedNames.empty()) { 3564 NNS = NestedNames.pop_back_val(); 3565 NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); 3566 Record.push_back(Kind); 3567 switch (Kind) { 3568 case NestedNameSpecifier::Identifier: 3569 AddIdentifierRef(NNS->getAsIdentifier(), Record); 3570 break; 3571 3572 case NestedNameSpecifier::Namespace: 3573 AddDeclRef(NNS->getAsNamespace(), Record); 3574 break; 3575 3576 case NestedNameSpecifier::NamespaceAlias: 3577 AddDeclRef(NNS->getAsNamespaceAlias(), Record); 3578 break; 3579 3580 case NestedNameSpecifier::TypeSpec: 3581 case NestedNameSpecifier::TypeSpecWithTemplate: 3582 AddTypeRef(QualType(NNS->getAsType(), 0), Record); 3583 Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); 3584 break; 3585 3586 case NestedNameSpecifier::Global: 3587 // Don't need to write an associated value. 3588 break; 3589 } 3590 } 3591} 3592 3593void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, 3594 RecordDataImpl &Record) { 3595 // Nested name specifiers usually aren't too long. I think that 8 would 3596 // typically accommodate the vast majority. 3597 llvm::SmallVector<NestedNameSpecifierLoc , 8> NestedNames; 3598 3599 // Push each of the nested-name-specifiers's onto a stack for 3600 // serialization in reverse order. 3601 while (NNS) { 3602 NestedNames.push_back(NNS); 3603 NNS = NNS.getPrefix(); 3604 } 3605 3606 Record.push_back(NestedNames.size()); 3607 while(!NestedNames.empty()) { 3608 NNS = NestedNames.pop_back_val(); 3609 NestedNameSpecifier::SpecifierKind Kind 3610 = NNS.getNestedNameSpecifier()->getKind(); 3611 Record.push_back(Kind); 3612 switch (Kind) { 3613 case NestedNameSpecifier::Identifier: 3614 AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier(), Record); 3615 AddSourceRange(NNS.getLocalSourceRange(), Record); 3616 break; 3617 3618 case NestedNameSpecifier::Namespace: 3619 AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace(), Record); 3620 AddSourceRange(NNS.getLocalSourceRange(), Record); 3621 break; 3622 3623 case NestedNameSpecifier::NamespaceAlias: 3624 AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), Record); 3625 AddSourceRange(NNS.getLocalSourceRange(), Record); 3626 break; 3627 3628 case NestedNameSpecifier::TypeSpec: 3629 case NestedNameSpecifier::TypeSpecWithTemplate: 3630 Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); 3631 AddTypeLoc(NNS.getTypeLoc(), Record); 3632 AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record); 3633 break; 3634 3635 case NestedNameSpecifier::Global: 3636 AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record); 3637 break; 3638 } 3639 } 3640} 3641 3642void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) { 3643 TemplateName::NameKind Kind = Name.getKind(); 3644 Record.push_back(Kind); 3645 switch (Kind) { 3646 case TemplateName::Template: 3647 AddDeclRef(Name.getAsTemplateDecl(), Record); 3648 break; 3649 3650 case TemplateName::OverloadedTemplate: { 3651 OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate(); 3652 Record.push_back(OvT->size()); 3653 for (OverloadedTemplateStorage::iterator I = OvT->begin(), E = OvT->end(); 3654 I != E; ++I) 3655 AddDeclRef(*I, Record); 3656 break; 3657 } 3658 3659 case TemplateName::QualifiedTemplate: { 3660 QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); 3661 AddNestedNameSpecifier(QualT->getQualifier(), Record); 3662 Record.push_back(QualT->hasTemplateKeyword()); 3663 AddDeclRef(QualT->getTemplateDecl(), Record); 3664 break; 3665 } 3666 3667 case TemplateName::DependentTemplate: { 3668 DependentTemplateName *DepT = Name.getAsDependentTemplateName(); 3669 AddNestedNameSpecifier(DepT->getQualifier(), Record); 3670 Record.push_back(DepT->isIdentifier()); 3671 if (DepT->isIdentifier()) 3672 AddIdentifierRef(DepT->getIdentifier(), Record); 3673 else 3674 Record.push_back(DepT->getOperator()); 3675 break; 3676 } 3677 3678 case TemplateName::SubstTemplateTemplateParmPack: { 3679 SubstTemplateTemplateParmPackStorage *SubstPack 3680 = Name.getAsSubstTemplateTemplateParmPack(); 3681 AddDeclRef(SubstPack->getParameterPack(), Record); 3682 AddTemplateArgument(SubstPack->getArgumentPack(), Record); 3683 break; 3684 } 3685 } 3686} 3687 3688void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, 3689 RecordDataImpl &Record) { 3690 Record.push_back(Arg.getKind()); 3691 switch (Arg.getKind()) { 3692 case TemplateArgument::Null: 3693 break; 3694 case TemplateArgument::Type: 3695 AddTypeRef(Arg.getAsType(), Record); 3696 break; 3697 case TemplateArgument::Declaration: 3698 AddDeclRef(Arg.getAsDecl(), Record); 3699 break; 3700 case TemplateArgument::Integral: 3701 AddAPSInt(*Arg.getAsIntegral(), Record); 3702 AddTypeRef(Arg.getIntegralType(), Record); 3703 break; 3704 case TemplateArgument::Template: 3705 AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record); 3706 break; 3707 case TemplateArgument::TemplateExpansion: 3708 AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record); 3709 if (llvm::Optional<unsigned> NumExpansions = Arg.getNumTemplateExpansions()) 3710 Record.push_back(*NumExpansions + 1); 3711 else 3712 Record.push_back(0); 3713 break; 3714 case TemplateArgument::Expression: 3715 AddStmt(Arg.getAsExpr()); 3716 break; 3717 case TemplateArgument::Pack: 3718 Record.push_back(Arg.pack_size()); 3719 for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end(); 3720 I != E; ++I) 3721 AddTemplateArgument(*I, Record); 3722 break; 3723 } 3724} 3725 3726void 3727ASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams, 3728 RecordDataImpl &Record) { 3729 assert(TemplateParams && "No TemplateParams!"); 3730 AddSourceLocation(TemplateParams->getTemplateLoc(), Record); 3731 AddSourceLocation(TemplateParams->getLAngleLoc(), Record); 3732 AddSourceLocation(TemplateParams->getRAngleLoc(), Record); 3733 Record.push_back(TemplateParams->size()); 3734 for (TemplateParameterList::const_iterator 3735 P = TemplateParams->begin(), PEnd = TemplateParams->end(); 3736 P != PEnd; ++P) 3737 AddDeclRef(*P, Record); 3738} 3739 3740/// \brief Emit a template argument list. 3741void 3742ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, 3743 RecordDataImpl &Record) { 3744 assert(TemplateArgs && "No TemplateArgs!"); 3745 Record.push_back(TemplateArgs->size()); 3746 for (int i=0, e = TemplateArgs->size(); i != e; ++i) 3747 AddTemplateArgument(TemplateArgs->get(i), Record); 3748} 3749 3750 3751void 3752ASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record) { 3753 Record.push_back(Set.size()); 3754 for (UnresolvedSetImpl::const_iterator 3755 I = Set.begin(), E = Set.end(); I != E; ++I) { 3756 AddDeclRef(I.getDecl(), Record); 3757 Record.push_back(I.getAccess()); 3758 } 3759} 3760 3761void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, 3762 RecordDataImpl &Record) { 3763 Record.push_back(Base.isVirtual()); 3764 Record.push_back(Base.isBaseOfClass()); 3765 Record.push_back(Base.getAccessSpecifierAsWritten()); 3766 Record.push_back(Base.getInheritConstructors()); 3767 AddTypeSourceInfo(Base.getTypeSourceInfo(), Record); 3768 AddSourceRange(Base.getSourceRange(), Record); 3769 AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc() 3770 : SourceLocation(), 3771 Record); 3772} 3773 3774void ASTWriter::FlushCXXBaseSpecifiers() { 3775 RecordData Record; 3776 for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) { 3777 Record.clear(); 3778 3779 // Record the offset of this base-specifier set. 3780 unsigned Index = CXXBaseSpecifiersToWrite[I].ID - FirstCXXBaseSpecifiersID; 3781 if (Index == CXXBaseSpecifiersOffsets.size()) 3782 CXXBaseSpecifiersOffsets.push_back(Stream.GetCurrentBitNo()); 3783 else { 3784 if (Index > CXXBaseSpecifiersOffsets.size()) 3785 CXXBaseSpecifiersOffsets.resize(Index + 1); 3786 CXXBaseSpecifiersOffsets[Index] = Stream.GetCurrentBitNo(); 3787 } 3788 3789 const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases, 3790 *BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd; 3791 Record.push_back(BEnd - B); 3792 for (; B != BEnd; ++B) 3793 AddCXXBaseSpecifier(*B, Record); 3794 Stream.EmitRecord(serialization::DECL_CXX_BASE_SPECIFIERS, Record); 3795 3796 // Flush any expressions that were written as part of the base specifiers. 3797 FlushStmts(); 3798 } 3799 3800 CXXBaseSpecifiersToWrite.clear(); 3801} 3802 3803void ASTWriter::AddCXXCtorInitializers( 3804 const CXXCtorInitializer * const *CtorInitializers, 3805 unsigned NumCtorInitializers, 3806 RecordDataImpl &Record) { 3807 Record.push_back(NumCtorInitializers); 3808 for (unsigned i=0; i != NumCtorInitializers; ++i) { 3809 const CXXCtorInitializer *Init = CtorInitializers[i]; 3810 3811 if (Init->isBaseInitializer()) { 3812 Record.push_back(CTOR_INITIALIZER_BASE); 3813 AddTypeSourceInfo(Init->getBaseClassInfo(), Record); 3814 Record.push_back(Init->isBaseVirtual()); 3815 } else if (Init->isDelegatingInitializer()) { 3816 Record.push_back(CTOR_INITIALIZER_DELEGATING); 3817 AddDeclRef(Init->getTargetConstructor(), Record); 3818 } else if (Init->isMemberInitializer()){ 3819 Record.push_back(CTOR_INITIALIZER_MEMBER); 3820 AddDeclRef(Init->getMember(), Record); 3821 } else { 3822 Record.push_back(CTOR_INITIALIZER_INDIRECT_MEMBER); 3823 AddDeclRef(Init->getIndirectMember(), Record); 3824 } 3825 3826 AddSourceLocation(Init->getMemberLocation(), Record); 3827 AddStmt(Init->getInit()); 3828 AddSourceLocation(Init->getLParenLoc(), Record); 3829 AddSourceLocation(Init->getRParenLoc(), Record); 3830 Record.push_back(Init->isWritten()); 3831 if (Init->isWritten()) { 3832 Record.push_back(Init->getSourceOrder()); 3833 } else { 3834 Record.push_back(Init->getNumArrayIndices()); 3835 for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i) 3836 AddDeclRef(Init->getArrayIndex(i), Record); 3837 } 3838 } 3839} 3840 3841void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) { 3842 assert(D->DefinitionData); 3843 struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; 3844 Record.push_back(Data.UserDeclaredConstructor); 3845 Record.push_back(Data.UserDeclaredCopyConstructor); 3846 Record.push_back(Data.UserDeclaredCopyAssignment); 3847 Record.push_back(Data.UserDeclaredDestructor); 3848 Record.push_back(Data.Aggregate); 3849 Record.push_back(Data.PlainOldData); 3850 Record.push_back(Data.Empty); 3851 Record.push_back(Data.Polymorphic); 3852 Record.push_back(Data.Abstract); 3853 Record.push_back(Data.IsStandardLayout); 3854 Record.push_back(Data.HasNoNonEmptyBases); 3855 Record.push_back(Data.HasPrivateFields); 3856 Record.push_back(Data.HasProtectedFields); 3857 Record.push_back(Data.HasPublicFields); 3858 Record.push_back(Data.HasMutableFields); 3859 Record.push_back(Data.HasTrivialDefaultConstructor); 3860 Record.push_back(Data.HasConstExprNonCopyMoveConstructor); 3861 Record.push_back(Data.HasTrivialCopyConstructor); 3862 Record.push_back(Data.HasTrivialMoveConstructor); 3863 Record.push_back(Data.HasTrivialCopyAssignment); 3864 Record.push_back(Data.HasTrivialMoveAssignment); 3865 Record.push_back(Data.HasTrivialDestructor); 3866 Record.push_back(Data.HasNonLiteralTypeFieldsOrBases); 3867 Record.push_back(Data.ComputedVisibleConversions); 3868 Record.push_back(Data.UserProvidedDefaultConstructor); 3869 Record.push_back(Data.DeclaredDefaultConstructor); 3870 Record.push_back(Data.DeclaredCopyConstructor); 3871 Record.push_back(Data.DeclaredCopyAssignment); 3872 Record.push_back(Data.DeclaredDestructor); 3873 3874 Record.push_back(Data.NumBases); 3875 if (Data.NumBases > 0) 3876 AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases, 3877 Record); 3878 3879 // FIXME: Make VBases lazily computed when needed to avoid storing them. 3880 Record.push_back(Data.NumVBases); 3881 if (Data.NumVBases > 0) 3882 AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases, 3883 Record); 3884 3885 AddUnresolvedSet(Data.Conversions, Record); 3886 AddUnresolvedSet(Data.VisibleConversions, Record); 3887 // Data.Definition is the owning decl, no need to write it. 3888 AddDeclRef(Data.FirstFriend, Record); 3889} 3890 3891void ASTWriter::ReaderInitialized(ASTReader *Reader) { 3892 assert(Reader && "Cannot remove chain"); 3893 assert(!Chain && "Cannot replace chain"); 3894 assert(FirstDeclID == NextDeclID && 3895 FirstTypeID == NextTypeID && 3896 FirstIdentID == NextIdentID && 3897 FirstSelectorID == NextSelectorID && 3898 FirstMacroID == NextMacroID && 3899 FirstCXXBaseSpecifiersID == NextCXXBaseSpecifiersID && 3900 "Setting chain after writing has started."); 3901 Chain = Reader; 3902 3903 FirstDeclID += Chain->getTotalNumDecls(); 3904 FirstTypeID += Chain->getTotalNumTypes(); 3905 FirstIdentID += Chain->getTotalNumIdentifiers(); 3906 FirstSelectorID += Chain->getTotalNumSelectors(); 3907 FirstMacroID += Chain->getTotalNumMacroDefinitions(); 3908 FirstCXXBaseSpecifiersID += Chain->getTotalNumCXXBaseSpecifiers(); 3909 NextDeclID = FirstDeclID; 3910 NextTypeID = FirstTypeID; 3911 NextIdentID = FirstIdentID; 3912 NextSelectorID = FirstSelectorID; 3913 NextMacroID = FirstMacroID; 3914 NextCXXBaseSpecifiersID = FirstCXXBaseSpecifiersID; 3915} 3916 3917void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) { 3918 IdentifierIDs[II] = ID; 3919 if (II->hasMacroDefinition()) 3920 DeserializedMacroNames.push_back(II); 3921} 3922 3923void ASTWriter::TypeRead(TypeIdx Idx, QualType T) { 3924 // Always take the highest-numbered type index. This copes with an interesting 3925 // case for chained AST writing where we schedule writing the type and then, 3926 // later, deserialize the type from another AST. In this case, we want to 3927 // keep the higher-numbered entry so that we can properly write it out to 3928 // the AST file. 3929 TypeIdx &StoredIdx = TypeIdxs[T]; 3930 if (Idx.getIndex() >= StoredIdx.getIndex()) 3931 StoredIdx = Idx; 3932} 3933 3934void ASTWriter::DeclRead(DeclID ID, const Decl *D) { 3935 DeclIDs[D] = ID; 3936} 3937 3938void ASTWriter::SelectorRead(SelectorID ID, Selector S) { 3939 SelectorIDs[S] = ID; 3940} 3941 3942void ASTWriter::MacroDefinitionRead(serialization::MacroID ID, 3943 MacroDefinition *MD) { 3944 MacroDefinitions[MD] = ID; 3945} 3946 3947void ASTWriter::CompletedTagDefinition(const TagDecl *D) { 3948 assert(D->isDefinition()); 3949 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 3950 // We are interested when a PCH decl is modified. 3951 if (RD->getPCHLevel() > 0) { 3952 // A forward reference was mutated into a definition. Rewrite it. 3953 // FIXME: This happens during template instantiation, should we 3954 // have created a new definition decl instead ? 3955 RewriteDecl(RD); 3956 } 3957 3958 for (CXXRecordDecl::redecl_iterator 3959 I = RD->redecls_begin(), E = RD->redecls_end(); I != E; ++I) { 3960 CXXRecordDecl *Redecl = cast<CXXRecordDecl>(*I); 3961 if (Redecl == RD) 3962 continue; 3963 3964 // We are interested when a PCH decl is modified. 3965 if (Redecl->getPCHLevel() > 0) { 3966 UpdateRecord &Record = DeclUpdates[Redecl]; 3967 Record.push_back(UPD_CXX_SET_DEFINITIONDATA); 3968 assert(Redecl->DefinitionData); 3969 assert(Redecl->DefinitionData->Definition == D); 3970 AddDeclRef(D, Record); // the DefinitionDecl 3971 } 3972 } 3973 } 3974} 3975void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { 3976 // TU and namespaces are handled elsewhere. 3977 if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC)) 3978 return; 3979 3980 if (!(D->getPCHLevel() == 0 && cast<Decl>(DC)->getPCHLevel() > 0)) 3981 return; // Not a source decl added to a DeclContext from PCH. 3982 3983 AddUpdatedDeclContext(DC); 3984} 3985 3986void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { 3987 assert(D->isImplicit()); 3988 if (!(D->getPCHLevel() == 0 && RD->getPCHLevel() > 0)) 3989 return; // Not a source member added to a class from PCH. 3990 if (!isa<CXXMethodDecl>(D)) 3991 return; // We are interested in lazily declared implicit methods. 3992 3993 // A decl coming from PCH was modified. 3994 assert(RD->isDefinition()); 3995 UpdateRecord &Record = DeclUpdates[RD]; 3996 Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER); 3997 AddDeclRef(D, Record); 3998} 3999 4000void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, 4001 const ClassTemplateSpecializationDecl *D) { 4002 // The specializations set is kept in the canonical template. 4003 TD = TD->getCanonicalDecl(); 4004 if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0)) 4005 return; // Not a source specialization added to a template from PCH. 4006 4007 UpdateRecord &Record = DeclUpdates[TD]; 4008 Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); 4009 AddDeclRef(D, Record); 4010} 4011 4012void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, 4013 const FunctionDecl *D) { 4014 // The specializations set is kept in the canonical template. 4015 TD = TD->getCanonicalDecl(); 4016 if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0)) 4017 return; // Not a source specialization added to a template from PCH. 4018 4019 UpdateRecord &Record = DeclUpdates[TD]; 4020 Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); 4021 AddDeclRef(D, Record); 4022} 4023 4024void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { 4025 if (D->getPCHLevel() == 0) 4026 return; // Declaration not imported from PCH. 4027 4028 // Implicit decl from a PCH was defined. 4029 // FIXME: Should implicit definition be a separate FunctionDecl? 4030 RewriteDecl(D); 4031} 4032 4033void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { 4034 if (D->getPCHLevel() == 0) 4035 return; 4036 4037 // Since the actual instantiation is delayed, this really means that we need 4038 // to update the instantiation location. 4039 UpdateRecord &Record = DeclUpdates[D]; 4040 Record.push_back(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER); 4041 AddSourceLocation( 4042 D->getMemberSpecializationInfo()->getPointOfInstantiation(), Record); 4043} 4044 4045ASTSerializationListener::~ASTSerializationListener() { } 4046