ASTWriter.cpp revision 89d9980bbc2e4a4ac86673e6ec16fb9f5babb63b
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===--- ASTWriter.cpp - AST File Writer ----------------------------------===// 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt// The LLVM Compiler Infrastructure 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// This file is distributed under the University of Illinois Open Source 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// License. See LICENSE.TXT for details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// This file defines the ASTWriter class, which writes AST files. 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Serialization/ASTWriter.h" 1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "clang/Serialization/ASTSerializationListener.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ASTCommon.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Sema/Sema.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Sema/IdentifierResolver.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/ASTContext.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/Decl.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/DeclContextInternals.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/DeclTemplate.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/DeclFriend.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/Expr.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/ExprCXX.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/Type.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/TypeLocVisitor.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Serialization/ASTReader.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/MacroInfo.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/PreprocessingRecord.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/Preprocessor.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/HeaderSearch.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/FileManager.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/FileSystemStatCache.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/OnDiskHashTable.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/SourceManager.h" 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/SourceManagerInternals.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/TargetInfo.h" 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/Version.h" 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/APFloat.h" 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/APInt.h" 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/StringExtras.h" 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Bitcode/BitstreamWriter.h" 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Support/MemoryBuffer.h" 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Support/Path.h" 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <cstdio> 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing namespace clang; 48f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtusing namespace clang::serialization; 49f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttemplate <typename T, typename Allocator> 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtT *data(std::vector<T, Allocator> &v) { 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return v.empty() ? 0 : &v.front(); 5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttemplate <typename T, typename Allocator> 55a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtconst T *data(const std::vector<T, Allocator> &v) { 56a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return v.empty() ? 0 : &v.front(); 57cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 58cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// Type serialization 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace { 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt class ASTTypeWriter { 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTWriter &Writer; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTWriter::RecordDataImpl &Record; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public: 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /// \brief Type code that corresponds to the record generated. 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TypeCode Code; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) 7361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { } 7461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 7561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void VisitArrayType(const ArrayType *T); 7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void VisitFunctionType(const FunctionType *T); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitTagType(const TagType *T); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T); 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define ABSTRACT_TYPE(Class, Base) 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/TypeNodes.def" 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(false && "Built-in types are never serialized"); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitComplexType(const ComplexType *T) { 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getElementType(), Record); 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_COMPLEX; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitPointerType(const PointerType *T) { 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getPointeeType(), Record); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_POINTER; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getPointeeType(), Record); 101d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt Code = TYPE_BLOCK_POINTER; 102d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 103d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 104d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) { 105d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt Writer.AddTypeRef(T->getPointeeType(), Record); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_LVALUE_REFERENCE; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) { 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getPointeeType(), Record); 111391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt Code = TYPE_RVALUE_REFERENCE; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) { 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getPointeeType(), Record); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(QualType(T->getClass(), 0), Record); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_MEMBER_POINTER; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitArrayType(const ArrayType *T) { 1211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddTypeRef(T->getElementType(), Record); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getSizeModifier()); // FIXME: stable values 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) { 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitArrayType(T); 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddAPInt(T->getSize(), Record); 129f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Code = TYPE_CONSTANT_ARRAY; 130df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt} 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 132818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) { 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitArrayType(T); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_INCOMPLETE_ARRAY; 13504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 13604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { 13804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt VisitArrayType(T); 13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Writer.AddSourceLocation(T->getLBracketLoc(), Record); 14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Writer.AddSourceLocation(T->getRBracketLoc(), Record); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddStmt(T->getSizeExpr()); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_VARIABLE_ARRAY; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitVectorType(const VectorType *T) { 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getElementType(), Record); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getNumElements()); 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getVectorKind()); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_VECTOR; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) { 1531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt VisitVectorType(T); 1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Code = TYPE_EXT_VECTOR; 1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid ASTTypeWriter::VisitFunctionType(const FunctionType *T) { 1581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddTypeRef(T->getResultType(), Record); 15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt FunctionType::ExtInfo C = T->getExtInfo(); 16004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Record.push_back(C.getNoReturn()); 16104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Record.push_back(C.getRegParm()); 16204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // FIXME: need to stabilize encoding of calling convention... 16304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Record.push_back(C.getCC()); 16404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 16661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { 16761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt VisitFunctionType(T); 16861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Code = TYPE_FUNCTION_NO_PROTO; 16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { 17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt VisitFunctionType(T); 17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Record.push_back(T->getNumArgs()); 17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I) 17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddTypeRef(T->getArgType(I), Record); 17661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Record.push_back(T->isVariadic()); 17761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Record.push_back(T->getTypeQuals()); 17861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Record.push_back(T->hasExceptionSpec()); 17961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Record.push_back(T->hasAnyExceptionSpec()); 18061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Record.push_back(T->getNumExceptions()); 18161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getExceptionType(I), Record); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_FUNCTION_PROTO; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddDeclRef(T->getDecl(), Record); 18834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt Code = TYPE_UNRESOLVED_USING; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitTypedefType(const TypedefType *T) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddDeclRef(T->getDecl(), Record); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(!T->isCanonicalUnqualified() && "Invalid typedef ?"); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_TYPEDEF; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddStmt(T->getUnderlyingExpr()); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_TYPEOF_EXPR; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) { 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getUnderlyingType(), Record); 205d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt Code = TYPE_TYPEOF; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddStmt(T->getUnderlyingExpr()); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_DECLTYPE; 21104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 21204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid ASTTypeWriter::VisitTagType(const TagType *T) { 21404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Record.push_back(T->isDependentType()); 21504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Writer.AddDeclRef(T->getDecl(), Record); 21604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt assert(!T->isBeingDefined() && 21704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "Cannot serialize in the middle of a type definition"); 21804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 21904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitRecordType(const RecordType *T) { 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitTagType(T); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_RECORD; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitEnumType(const EnumType *T) { 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitTagType(T); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_ENUM; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitSubstTemplateTypeParmType( 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const SubstTemplateTypeParmType *T) { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getReplacementType(), Record); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_SUBST_TEMPLATE_TYPE_PARM; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitTemplateSpecializationType( 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const TemplateSpecializationType *T) { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->isDependentType()); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTemplateName(T->getTemplateName(), Record); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getNumArgs()); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end(); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArgI != ArgE; ++ArgI) 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTemplateArgument(*ArgI, Record); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType() 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : T->getCanonicalTypeInternal(), 249c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Record); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_TEMPLATE_SPECIALIZATION; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitArrayType(T); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddStmt(T->getSizeExpr()); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceRange(T->getBracketsRange(), Record); 258b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt Code = TYPE_DEPENDENT_SIZED_ARRAY; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitDependentSizedExtVectorType( 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const DependentSizedExtVectorType *T) { 2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // FIXME: Serialize this type (C++ only) 2651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt assert(false && "Cannot serialize dependent sized extended vector types"); 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getDepth()); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getIndex()); 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->isParameterPack()); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddIdentifierRef(T->getName(), Record); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_TEMPLATE_TYPE_PARM; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitDependentNameType(const DependentNameType *T) { 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getKeyword()); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddIdentifierRef(T->getIdentifier(), Record); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType() 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : T->getCanonicalTypeInternal(), 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_DEPENDENT_NAME; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitDependentTemplateSpecializationType( 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const DependentTemplateSpecializationType *T) { 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getKeyword()); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddIdentifierRef(T->getIdentifier(), Record); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getNumArgs()); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (DependentTemplateSpecializationType::iterator 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt I = T->begin(), E = T->end(); I != E; ++I) 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTemplateArgument(*I, Record); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getKeyword()); 30334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getNamedType(), Record); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_ELABORATED; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) { 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddDeclRef(T->getDecl(), Record); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getInjectedSpecializationType(), Record); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_INJECTED_CLASS_NAME; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddDeclRef(T->getDecl(), Record); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_OBJC_INTERFACE; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 319bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidtvoid ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getBaseType(), Record); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(T->getNumProtocols()); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ObjCObjectType::qual_iterator I = T->qual_begin(), 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt E = T->qual_end(); I != E; ++I) 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddDeclRef(*I, Record); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_OBJC_OBJECT; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddTypeRef(T->getPointeeType(), Record); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Code = TYPE_OBJC_OBJECT_POINTER; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace { 335d5c075b0c218277d0f926daf1f9eff974b9656dcDmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTWriter &Writer; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTWriter::RecordDataImpl &Record; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic: 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : Writer(Writer), Record(Record) { } 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define ABSTRACT_TYPELOC(CLASS, PARENT) 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TYPELOC(CLASS, PARENT) \ 346c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/TypeLocNodes.def" 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitArrayTypeLoc(ArrayTypeLoc TyLoc); 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc); 351444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt}; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // nothing to do 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceLocation(TL.getBuiltinLoc(), Record); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TL.needsExtraLocalData()) { 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(TL.getWrittenTypeSpec()); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(TL.getWrittenSignSpec()); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(TL.getWrittenWidthSpec()); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(TL.hasModeAttr()); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { 368391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceLocation(TL.getStarLoc(), Record); 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceLocation(TL.getCaretLoc(), Record); 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceLocation(TL.getAmpLoc(), Record); 378f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt} 37904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 38004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record); 38104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 38204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceLocation(TL.getStarLoc(), Record); 38487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen} 38534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtvoid TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceLocation(TL.getLBracketLoc(), Record); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddSourceLocation(TL.getRBracketLoc(), Record); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(TL.getSizeExpr() ? 1 : 0); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TL.getSizeExpr()) 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Writer.AddStmt(TL.getSizeExpr()); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { 393cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt VisitArrayTypeLoc(TL); 394cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 395cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtvoid TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { 396cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt VisitArrayTypeLoc(TL); 397cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 398cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtvoid TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitArrayTypeLoc(TL); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid TypeLocWriter::VisitDependentSizedArrayTypeLoc( 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DependentSizedArrayTypeLoc TL) { 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitArrayTypeLoc(TL); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DependentSizedExtVectorTypeLoc TL) { 40704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 4081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { 4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 4111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 412a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtvoid TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { 413a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 4141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { 4161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddSourceLocation(TL.getLParenLoc(), Record); 4171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddSourceLocation(TL.getRParenLoc(), Record); 4181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Record.push_back(TL.getTrailingReturn()); 4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 4201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddDeclRef(TL.getArg(i), Record); 4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { 4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt VisitFunctionTypeLoc(TL); 4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { 4261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt VisitFunctionTypeLoc(TL); 4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 4291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 43104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 43204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 43361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 43461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 43561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 43661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getLParenLoc(), Record); 43761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getRParenLoc(), Record); 43861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 43961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 44061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 44161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getLParenLoc(), Record); 44261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getRParenLoc(), Record); 44361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record); 44461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 44561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 44661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 44761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 44861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { 44961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 45061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 45161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { 45261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 45304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 45404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 45504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 45604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 457051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtvoid TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( 458051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt SubstTemplateTypeParmTypeLoc TL) { 459051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 460f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 46161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid TypeLocWriter::VisitTemplateSpecializationTypeLoc( 46261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt TemplateSpecializationTypeLoc TL) { 46361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record); 464f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 46561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 46661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 46761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(), 46861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt TL.getArgLoc(i).getLocInfo(), Record); 46961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 47061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { 47161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 472f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceRange(TL.getQualifierRange(), Record); 473f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 474f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 475f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 476f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 477f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { 478f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 479f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceRange(TL.getQualifierRange(), Record); 480f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 481f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 482f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( 483f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt DependentTemplateSpecializationTypeLoc TL) { 484f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 485f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceRange(TL.getQualifierRange(), Record); 486f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 487f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 488f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 489f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) 490f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(), 491f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt TL.getArgLoc(I).getLocInfo(), Record); 492f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 493f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 494f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Writer.AddSourceLocation(TL.getNameLoc(), Record); 495f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 496f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 497f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Record.push_back(TL.hasBaseTypeAsWritten()); 49861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 49961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 5001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) 5011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); 5021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 5031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 5041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Writer.AddSourceLocation(TL.getStarLoc(), Record); 50561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 50661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 507a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt//===----------------------------------------------------------------------===// 508a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt// ASTWriter Implementation 509a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt//===----------------------------------------------------------------------===// 510051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 5110207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidtstatic void EmitBlockID(unsigned ID, const char *Name, 5120207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt llvm::BitstreamWriter &Stream, 513051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ASTWriter::RecordDataImpl &Record) { 514051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt Record.clear(); 515051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt Record.push_back(ID); 516051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Emit the block name if present. 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Name == 0 || Name[0] == 0) return; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.clear(); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*Name) 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(*Name++); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record); 524cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void EmitRecordID(unsigned ID, const char *Name, 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::BitstreamWriter &Stream, 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTWriter::RecordDataImpl &Record) { 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.clear(); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Record.push_back(ID); 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*Name) 5329866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt Record.push_back(*Name++); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void AddStmtsExprs(llvm::BitstreamWriter &Stream, 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTWriter::RecordDataImpl &Record) { 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_STOP); 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_NULL_PTR); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_NULL); 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_COMPOUND); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_CASE); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_DEFAULT); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_LABEL); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_IF); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_SWITCH); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_WHILE); 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_DO); 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_FOR); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_GOTO); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_INDIRECT_GOTO); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_CONTINUE); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_BREAK); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_RETURN); 556ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt RECORD(STMT_DECL); 557ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt RECORD(STMT_ASM); 558f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_PREDEFINED); 559f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_DECL_REF); 560f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_INTEGER_LITERAL); 561f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_FLOATING_LITERAL); 562f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_IMAGINARY_LITERAL); 563f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_STRING_LITERAL); 564f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_CHARACTER_LITERAL); 565f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_PAREN); 566f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_UNARY_OPERATOR); 567f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RECORD(EXPR_SIZEOF_ALIGN_OF); 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_ARRAY_SUBSCRIPT); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CALL); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_MEMBER); 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_BINARY_OPERATOR); 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CONDITIONAL_OPERATOR); 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_IMPLICIT_CAST); 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CSTYLE_CAST); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_COMPOUND_LITERAL); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_EXT_VECTOR_ELEMENT); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_INIT_LIST); 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_DESIGNATED_INIT); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_IMPLICIT_VALUE_INIT); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_VA_ARG); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_ADDR_LABEL); 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_STMT); 5845460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt RECORD(EXPR_TYPES_COMPATIBLE); 58504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RECORD(EXPR_CHOOSE); 58604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RECORD(EXPR_GNU_NULL); 58761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RECORD(EXPR_SHUFFLE_VECTOR); 58804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RECORD(EXPR_BLOCK); 58961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RECORD(EXPR_BLOCK_DECL_REF); 590d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt RECORD(EXPR_OBJC_STRING_LITERAL); 5918da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt RECORD(EXPR_OBJC_ENCODE); 5928da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt RECORD(EXPR_OBJC_SELECTOR_EXPR); 5938da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt RECORD(EXPR_OBJC_PROTOCOL_EXPR); 5948da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt RECORD(EXPR_OBJC_IVAR_REF_EXPR); 5958da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt RECORD(EXPR_OBJC_PROPERTY_REF_EXPR); 5968da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt RECORD(EXPR_OBJC_KVC_REF_EXPR); 59751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt RECORD(EXPR_OBJC_MESSAGE_EXPR); 5988da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt RECORD(STMT_OBJC_FOR_COLLECTION); 599391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt RECORD(STMT_OBJC_CATCH); 600391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt RECORD(STMT_OBJC_FINALLY); 601391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt RECORD(STMT_OBJC_AT_TRY); 602391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt RECORD(STMT_OBJC_AT_SYNCHRONIZED); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(STMT_OBJC_AT_THROW); 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CXX_OPERATOR_CALL); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CXX_CONSTRUCT); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CXX_STATIC_CAST); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CXX_DYNAMIC_CAST); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CXX_REINTERPRET_CAST); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CXX_CONST_CAST); 610818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RECORD(EXPR_CXX_FUNCTIONAL_CAST); 611cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt RECORD(EXPR_CXX_BOOL_LITERAL); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(EXPR_CXX_NULL_PTR_LITERAL); 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef RECORD 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ASTWriter::WriteBlockInfoBlock() { 617391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt RecordData Record; 618391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record) 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // AST Top-Level Block. 62404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt BLOCK(AST_BLOCK); 625344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt RECORD(ORIGINAL_FILE_NAME); 626717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt RECORD(TYPE_OFFSET); 627717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt RECORD(DECL_OFFSET); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(LANGUAGE_OPTIONS); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RECORD(METADATA); 630 RECORD(IDENTIFIER_OFFSET); 631 RECORD(IDENTIFIER_TABLE); 632 RECORD(EXTERNAL_DEFINITIONS); 633 RECORD(SPECIAL_TYPES); 634 RECORD(STATISTICS); 635 RECORD(TENTATIVE_DEFINITIONS); 636 RECORD(UNUSED_FILESCOPED_DECLS); 637 RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS); 638 RECORD(SELECTOR_OFFSETS); 639 RECORD(METHOD_POOL); 640 RECORD(PP_COUNTER_VALUE); 641 RECORD(SOURCE_LOCATION_OFFSETS); 642 RECORD(SOURCE_LOCATION_PRELOADS); 643 RECORD(STAT_CACHE); 644 RECORD(EXT_VECTOR_DECLS); 645 RECORD(VERSION_CONTROL_BRANCH_REVISION); 646 RECORD(MACRO_DEFINITION_OFFSETS); 647 RECORD(CHAINED_METADATA); 648 RECORD(REFERENCED_SELECTOR_POOL); 649 650 // SourceManager Block. 651 BLOCK(SOURCE_MANAGER_BLOCK); 652 RECORD(SM_SLOC_FILE_ENTRY); 653 RECORD(SM_SLOC_BUFFER_ENTRY); 654 RECORD(SM_SLOC_BUFFER_BLOB); 655 RECORD(SM_SLOC_INSTANTIATION_ENTRY); 656 RECORD(SM_LINE_TABLE); 657 658 // Preprocessor Block. 659 BLOCK(PREPROCESSOR_BLOCK); 660 RECORD(PP_MACRO_OBJECT_LIKE); 661 RECORD(PP_MACRO_FUNCTION_LIKE); 662 RECORD(PP_TOKEN); 663 RECORD(PP_MACRO_INSTANTIATION); 664 RECORD(PP_MACRO_DEFINITION); 665 666 // Decls and Types block. 667 BLOCK(DECLTYPES_BLOCK); 668 RECORD(TYPE_EXT_QUAL); 669 RECORD(TYPE_COMPLEX); 670 RECORD(TYPE_POINTER); 671 RECORD(TYPE_BLOCK_POINTER); 672 RECORD(TYPE_LVALUE_REFERENCE); 673 RECORD(TYPE_RVALUE_REFERENCE); 674 RECORD(TYPE_MEMBER_POINTER); 675 RECORD(TYPE_CONSTANT_ARRAY); 676 RECORD(TYPE_INCOMPLETE_ARRAY); 677 RECORD(TYPE_VARIABLE_ARRAY); 678 RECORD(TYPE_VECTOR); 679 RECORD(TYPE_EXT_VECTOR); 680 RECORD(TYPE_FUNCTION_PROTO); 681 RECORD(TYPE_FUNCTION_NO_PROTO); 682 RECORD(TYPE_TYPEDEF); 683 RECORD(TYPE_TYPEOF_EXPR); 684 RECORD(TYPE_TYPEOF); 685 RECORD(TYPE_RECORD); 686 RECORD(TYPE_ENUM); 687 RECORD(TYPE_OBJC_INTERFACE); 688 RECORD(TYPE_OBJC_OBJECT); 689 RECORD(TYPE_OBJC_OBJECT_POINTER); 690 RECORD(DECL_TRANSLATION_UNIT); 691 RECORD(DECL_TYPEDEF); 692 RECORD(DECL_ENUM); 693 RECORD(DECL_RECORD); 694 RECORD(DECL_ENUM_CONSTANT); 695 RECORD(DECL_FUNCTION); 696 RECORD(DECL_OBJC_METHOD); 697 RECORD(DECL_OBJC_INTERFACE); 698 RECORD(DECL_OBJC_PROTOCOL); 699 RECORD(DECL_OBJC_IVAR); 700 RECORD(DECL_OBJC_AT_DEFS_FIELD); 701 RECORD(DECL_OBJC_CLASS); 702 RECORD(DECL_OBJC_FORWARD_PROTOCOL); 703 RECORD(DECL_OBJC_CATEGORY); 704 RECORD(DECL_OBJC_CATEGORY_IMPL); 705 RECORD(DECL_OBJC_IMPLEMENTATION); 706 RECORD(DECL_OBJC_COMPATIBLE_ALIAS); 707 RECORD(DECL_OBJC_PROPERTY); 708 RECORD(DECL_OBJC_PROPERTY_IMPL); 709 RECORD(DECL_FIELD); 710 RECORD(DECL_VAR); 711 RECORD(DECL_IMPLICIT_PARAM); 712 RECORD(DECL_PARM_VAR); 713 RECORD(DECL_FILE_SCOPE_ASM); 714 RECORD(DECL_BLOCK); 715 RECORD(DECL_CONTEXT_LEXICAL); 716 RECORD(DECL_CONTEXT_VISIBLE); 717 // Statements and Exprs can occur in the Decls and Types block. 718 AddStmtsExprs(Stream, Record); 719#undef RECORD 720#undef BLOCK 721 Stream.ExitBlock(); 722} 723 724/// \brief Adjusts the given filename to only write out the portion of the 725/// filename that is not part of the system root directory. 726/// 727/// \param Filename the file name to adjust. 728/// 729/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and 730/// the returned filename will be adjusted by this system root. 731/// 732/// \returns either the original filename (if it needs no adjustment) or the 733/// adjusted filename (which points into the @p Filename parameter). 734static const char * 735adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) { 736 assert(Filename && "No file name to adjust?"); 737 738 if (!isysroot) 739 return Filename; 740 741 // Verify that the filename and the system root have the same prefix. 742 unsigned Pos = 0; 743 for (; Filename[Pos] && isysroot[Pos]; ++Pos) 744 if (Filename[Pos] != isysroot[Pos]) 745 return Filename; // Prefixes don't match. 746 747 // We hit the end of the filename before we hit the end of the system root. 748 if (!Filename[Pos]) 749 return Filename; 750 751 // If the file name has a '/' at the current position, skip over the '/'. 752 // We distinguish sysroot-based includes from absolute includes by the 753 // absence of '/' at the beginning of sysroot-based includes. 754 if (Filename[Pos] == '/') 755 ++Pos; 756 757 return Filename + Pos; 758} 759 760/// \brief Write the AST metadata (e.g., i686-apple-darwin9). 761void ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot) { 762 using namespace llvm; 763 764 // Metadata 765 const TargetInfo &Target = Context.Target; 766 BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev(); 767 MetaAbbrev->Add(BitCodeAbbrevOp( 768 Chain ? CHAINED_METADATA : METADATA)); 769 MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major 770 MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor 771 MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major 772 MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor 773 MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable 774 // Target triple or chained PCH name 775 MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 776 unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev); 777 778 RecordData Record; 779 Record.push_back(Chain ? CHAINED_METADATA : METADATA); 780 Record.push_back(VERSION_MAJOR); 781 Record.push_back(VERSION_MINOR); 782 Record.push_back(CLANG_VERSION_MAJOR); 783 Record.push_back(CLANG_VERSION_MINOR); 784 Record.push_back(isysroot != 0); 785 // FIXME: This writes the absolute path for chained headers. 786 const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple(); 787 Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr); 788 789 // Original file name 790 SourceManager &SM = Context.getSourceManager(); 791 if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { 792 BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev(); 793 FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE_NAME)); 794 FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 795 unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev); 796 797 llvm::sys::Path MainFilePath(MainFile->getName()); 798 799 MainFilePath.makeAbsolute(); 800 801 const char *MainFileNameStr = MainFilePath.c_str(); 802 MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, 803 isysroot); 804 RecordData Record; 805 Record.push_back(ORIGINAL_FILE_NAME); 806 Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); 807 } 808 809 // Repository branch/version information. 810 BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev(); 811 RepoAbbrev->Add(BitCodeAbbrevOp(VERSION_CONTROL_BRANCH_REVISION)); 812 RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag 813 unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev); 814 Record.clear(); 815 Record.push_back(VERSION_CONTROL_BRANCH_REVISION); 816 Stream.EmitRecordWithBlob(RepoAbbrevCode, Record, 817 getClangFullRepositoryVersion()); 818} 819 820/// \brief Write the LangOptions structure. 821void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { 822 RecordData Record; 823 Record.push_back(LangOpts.Trigraphs); 824 Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments. 825 Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers. 826 Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode. 827 Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc) 828 Record.push_back(LangOpts.GNUKeywords); // Allow GNU-extension keywords 829 Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'. 830 Record.push_back(LangOpts.Digraphs); // C94, C99 and C++ 831 Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants. 832 Record.push_back(LangOpts.C99); // C99 Support 833 Record.push_back(LangOpts.Microsoft); // Microsoft extensions. 834 // LangOpts.MSCVersion is ignored because all it does it set a macro, which is 835 // already saved elsewhere. 836 Record.push_back(LangOpts.CPlusPlus); // C++ Support 837 Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support 838 Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords. 839 840 Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled. 841 Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled. 842 Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C 843 // modern abi enabled. 844 Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced 845 // modern abi enabled. 846 Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled.. 847 848 Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings 849 Record.push_back(LangOpts.WritableStrings); // Allow writable strings 850 Record.push_back(LangOpts.LaxVectorConversions); 851 Record.push_back(LangOpts.AltiVec); 852 Record.push_back(LangOpts.Exceptions); // Support exception handling. 853 Record.push_back(LangOpts.SjLjExceptions); 854 855 Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime. 856 Record.push_back(LangOpts.Freestanding); // Freestanding implementation 857 Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin) 858 859 // Whether static initializers are protected by locks. 860 Record.push_back(LangOpts.ThreadsafeStatics); 861 Record.push_back(LangOpts.POSIXThreads); 862 Record.push_back(LangOpts.Blocks); // block extension to C 863 Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if 864 // they are unused. 865 Record.push_back(LangOpts.MathErrno); // Math functions must respect errno 866 // (modulo the platform support). 867 868 Record.push_back(LangOpts.getSignedOverflowBehavior()); 869 Record.push_back(LangOpts.HeinousExtensions); 870 871 Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined. 872 Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be 873 // defined. 874 Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as 875 // opposed to __DYNAMIC__). 876 Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero. 877 878 Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be 879 // used (instead of C99 semantics). 880 Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined. 881 Record.push_back(LangOpts.AccessControl); // Whether C++ access control should 882 // be enabled. 883 Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or 884 // unsigned type 885 Record.push_back(LangOpts.ShortWChar); // force wchar_t to be unsigned short 886 Record.push_back(LangOpts.getGCMode()); 887 Record.push_back(LangOpts.getVisibilityMode()); 888 Record.push_back(LangOpts.getStackProtectorMode()); 889 Record.push_back(LangOpts.InstantiationDepth); 890 Record.push_back(LangOpts.OpenCL); 891 Record.push_back(LangOpts.CatchUndefined); 892 Record.push_back(LangOpts.ElideConstructors); 893 Record.push_back(LangOpts.SpellChecking); 894 Stream.EmitRecord(LANGUAGE_OPTIONS, Record); 895} 896 897//===----------------------------------------------------------------------===// 898// stat cache Serialization 899//===----------------------------------------------------------------------===// 900 901namespace { 902// Trait used for the on-disk hash table of stat cache results. 903class ASTStatCacheTrait { 904public: 905 typedef const char * key_type; 906 typedef key_type key_type_ref; 907 908 typedef struct stat data_type; 909 typedef const data_type &data_type_ref; 910 911 static unsigned ComputeHash(const char *path) { 912 return llvm::HashString(path); 913 } 914 915 std::pair<unsigned,unsigned> 916 EmitKeyDataLength(llvm::raw_ostream& Out, const char *path, 917 data_type_ref Data) { 918 unsigned StrLen = strlen(path); 919 clang::io::Emit16(Out, StrLen); 920 unsigned DataLen = 4 + 4 + 2 + 8 + 8; 921 clang::io::Emit8(Out, DataLen); 922 return std::make_pair(StrLen + 1, DataLen); 923 } 924 925 void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) { 926 Out.write(path, KeyLen); 927 } 928 929 void EmitData(llvm::raw_ostream &Out, key_type_ref, 930 data_type_ref Data, unsigned DataLen) { 931 using namespace clang::io; 932 uint64_t Start = Out.tell(); (void)Start; 933 934 Emit32(Out, (uint32_t) Data.st_ino); 935 Emit32(Out, (uint32_t) Data.st_dev); 936 Emit16(Out, (uint16_t) Data.st_mode); 937 Emit64(Out, (uint64_t) Data.st_mtime); 938 Emit64(Out, (uint64_t) Data.st_size); 939 940 assert(Out.tell() - Start == DataLen && "Wrong data length"); 941 } 942}; 943} // end anonymous namespace 944 945/// \brief Write the stat() system call cache to the AST file. 946void ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) { 947 // Build the on-disk hash table containing information about every 948 // stat() call. 949 OnDiskChainedHashTableGenerator<ASTStatCacheTrait> Generator; 950 unsigned NumStatEntries = 0; 951 for (MemorizeStatCalls::iterator Stat = StatCalls.begin(), 952 StatEnd = StatCalls.end(); 953 Stat != StatEnd; ++Stat, ++NumStatEntries) { 954 const char *Filename = Stat->first(); 955 Generator.insert(Filename, Stat->second); 956 } 957 958 // Create the on-disk hash table in a buffer. 959 llvm::SmallString<4096> StatCacheData; 960 uint32_t BucketOffset; 961 { 962 llvm::raw_svector_ostream Out(StatCacheData); 963 // Make sure that no bucket is at offset 0 964 clang::io::Emit32(Out, 0); 965 BucketOffset = Generator.Emit(Out); 966 } 967 968 // Create a blob abbreviation 969 using namespace llvm; 970 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 971 Abbrev->Add(BitCodeAbbrevOp(STAT_CACHE)); 972 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 973 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 974 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 975 unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev); 976 977 // Write the stat cache 978 RecordData Record; 979 Record.push_back(STAT_CACHE); 980 Record.push_back(BucketOffset); 981 Record.push_back(NumStatEntries); 982 Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str()); 983} 984 985//===----------------------------------------------------------------------===// 986// Source Manager Serialization 987//===----------------------------------------------------------------------===// 988 989/// \brief Create an abbreviation for the SLocEntry that refers to a 990/// file. 991static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { 992 using namespace llvm; 993 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 994 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY)); 995 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 996 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 997 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 998 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 999 // FileEntry fields. 1000 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size 1001 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time 1002 // HeaderFileInfo fields. 1003 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImport 1004 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // DirInfo 1005 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumIncludes 1006 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // ControllingMacro 1007 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 1008 return Stream.EmitAbbrev(Abbrev); 1009} 1010 1011/// \brief Create an abbreviation for the SLocEntry that refers to a 1012/// buffer. 1013static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { 1014 using namespace llvm; 1015 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1016 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY)); 1017 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1018 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 1019 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 1020 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1021 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob 1022 return Stream.EmitAbbrev(Abbrev); 1023} 1024 1025/// \brief Create an abbreviation for the SLocEntry that refers to a 1026/// buffer's blob. 1027static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) { 1028 using namespace llvm; 1029 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1030 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_BLOB)); 1031 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob 1032 return Stream.EmitAbbrev(Abbrev); 1033} 1034 1035/// \brief Create an abbreviation for the SLocEntry that refers to an 1036/// buffer. 1037static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) { 1038 using namespace llvm; 1039 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1040 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_INSTANTIATION_ENTRY)); 1041 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1042 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location 1043 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location 1044 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location 1045 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length 1046 return Stream.EmitAbbrev(Abbrev); 1047} 1048 1049/// \brief Writes the block containing the serialized form of the 1050/// source manager. 1051/// 1052/// TODO: We should probably use an on-disk hash table (stored in a 1053/// blob), indexed based on the file name, so that we only create 1054/// entries for files that we actually need. In the common case (no 1055/// errors), we probably won't have to create file entries for any of 1056/// the files in the AST. 1057void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, 1058 const Preprocessor &PP, 1059 const char *isysroot) { 1060 RecordData Record; 1061 1062 // Enter the source manager block. 1063 Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 3); 1064 1065 // Abbreviations for the various kinds of source-location entries. 1066 unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream); 1067 unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream); 1068 unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream); 1069 unsigned SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream); 1070 1071 // Write the line table. 1072 if (SourceMgr.hasLineTable()) { 1073 LineTableInfo &LineTable = SourceMgr.getLineTable(); 1074 1075 // Emit the file names 1076 Record.push_back(LineTable.getNumFilenames()); 1077 for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) { 1078 // Emit the file name 1079 const char *Filename = LineTable.getFilename(I); 1080 Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 1081 unsigned FilenameLen = Filename? strlen(Filename) : 0; 1082 Record.push_back(FilenameLen); 1083 if (FilenameLen) 1084 Record.insert(Record.end(), Filename, Filename + FilenameLen); 1085 } 1086 1087 // Emit the line entries 1088 for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end(); 1089 L != LEnd; ++L) { 1090 // Emit the file ID 1091 Record.push_back(L->first); 1092 1093 // Emit the line entries 1094 Record.push_back(L->second.size()); 1095 for (std::vector<LineEntry>::iterator LE = L->second.begin(), 1096 LEEnd = L->second.end(); 1097 LE != LEEnd; ++LE) { 1098 Record.push_back(LE->FileOffset); 1099 Record.push_back(LE->LineNo); 1100 Record.push_back(LE->FilenameID); 1101 Record.push_back((unsigned)LE->FileKind); 1102 Record.push_back(LE->IncludeOffset); 1103 } 1104 } 1105 Stream.EmitRecord(SM_LINE_TABLE, Record); 1106 } 1107 1108 // Write out the source location entry table. We skip the first 1109 // entry, which is always the same dummy entry. 1110 std::vector<uint32_t> SLocEntryOffsets; 1111 RecordData PreloadSLocs; 1112 unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0; 1113 SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID); 1114 for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size(); 1115 I != N; ++I) { 1116 // Get this source location entry. 1117 const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I); 1118 1119 // Record the offset of this source-location entry. 1120 SLocEntryOffsets.push_back(Stream.GetCurrentBitNo()); 1121 1122 // Figure out which record code to use. 1123 unsigned Code; 1124 if (SLoc->isFile()) { 1125 if (SLoc->getFile().getContentCache()->Entry) 1126 Code = SM_SLOC_FILE_ENTRY; 1127 else 1128 Code = SM_SLOC_BUFFER_ENTRY; 1129 } else 1130 Code = SM_SLOC_INSTANTIATION_ENTRY; 1131 Record.clear(); 1132 Record.push_back(Code); 1133 1134 Record.push_back(SLoc->getOffset()); 1135 if (SLoc->isFile()) { 1136 const SrcMgr::FileInfo &File = SLoc->getFile(); 1137 Record.push_back(File.getIncludeLoc().getRawEncoding()); 1138 Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding 1139 Record.push_back(File.hasLineDirectives()); 1140 1141 const SrcMgr::ContentCache *Content = File.getContentCache(); 1142 if (Content->Entry) { 1143 // The source location entry is a file. The blob associated 1144 // with this entry is the file name. 1145 1146 // Emit size/modification time for this file. 1147 Record.push_back(Content->Entry->getSize()); 1148 Record.push_back(Content->Entry->getModificationTime()); 1149 1150 // Emit header-search information associated with this file. 1151 HeaderFileInfo HFI; 1152 HeaderSearch &HS = PP.getHeaderSearchInfo(); 1153 if (Content->Entry->getUID() < HS.header_file_size()) 1154 HFI = HS.header_file_begin()[Content->Entry->getUID()]; 1155 Record.push_back(HFI.isImport); 1156 Record.push_back(HFI.DirInfo); 1157 Record.push_back(HFI.NumIncludes); 1158 AddIdentifierRef(HFI.ControllingMacro, Record); 1159 1160 // Turn the file name into an absolute path, if it isn't already. 1161 const char *Filename = Content->Entry->getName(); 1162 llvm::sys::Path FilePath(Filename, strlen(Filename)); 1163 FilePath.makeAbsolute(); 1164 Filename = FilePath.c_str(); 1165 1166 Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 1167 Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename); 1168 1169 // FIXME: For now, preload all file source locations, so that 1170 // we get the appropriate File entries in the reader. This is 1171 // a temporary measure. 1172 PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); 1173 } else { 1174 // The source location entry is a buffer. The blob associated 1175 // with this entry contains the contents of the buffer. 1176 1177 // We add one to the size so that we capture the trailing NULL 1178 // that is required by llvm::MemoryBuffer::getMemBuffer (on 1179 // the reader side). 1180 const llvm::MemoryBuffer *Buffer 1181 = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); 1182 const char *Name = Buffer->getBufferIdentifier(); 1183 Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record, 1184 llvm::StringRef(Name, strlen(Name) + 1)); 1185 Record.clear(); 1186 Record.push_back(SM_SLOC_BUFFER_BLOB); 1187 Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, 1188 llvm::StringRef(Buffer->getBufferStart(), 1189 Buffer->getBufferSize() + 1)); 1190 1191 if (strcmp(Name, "<built-in>") == 0) 1192 PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); 1193 } 1194 } else { 1195 // The source location entry is an instantiation. 1196 const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation(); 1197 Record.push_back(Inst.getSpellingLoc().getRawEncoding()); 1198 Record.push_back(Inst.getInstantiationLocStart().getRawEncoding()); 1199 Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding()); 1200 1201 // Compute the token length for this macro expansion. 1202 unsigned NextOffset = SourceMgr.getNextOffset(); 1203 if (I + 1 != N) 1204 NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset(); 1205 Record.push_back(NextOffset - SLoc->getOffset() - 1); 1206 Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record); 1207 } 1208 } 1209 1210 Stream.ExitBlock(); 1211 1212 if (SLocEntryOffsets.empty()) 1213 return; 1214 1215 // Write the source-location offsets table into the AST block. This 1216 // table is used for lazily loading source-location information. 1217 using namespace llvm; 1218 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1219 Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS)); 1220 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs 1221 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset 1222 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets 1223 unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev); 1224 1225 Record.clear(); 1226 Record.push_back(SOURCE_LOCATION_OFFSETS); 1227 Record.push_back(SLocEntryOffsets.size()); 1228 unsigned BaseOffset = Chain ? Chain->getNextSLocOffset() : 0; 1229 Record.push_back(SourceMgr.getNextOffset() - BaseOffset); 1230 Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, 1231 (const char *)data(SLocEntryOffsets), 1232 SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0])); 1233 1234 // Write the source location entry preloads array, telling the AST 1235 // reader which source locations entries it should load eagerly. 1236 Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs); 1237} 1238 1239//===----------------------------------------------------------------------===// 1240// Preprocessor Serialization 1241//===----------------------------------------------------------------------===// 1242 1243/// \brief Writes the block containing the serialized form of the 1244/// preprocessor. 1245/// 1246void ASTWriter::WritePreprocessor(const Preprocessor &PP) { 1247 RecordData Record; 1248 1249 // If the preprocessor __COUNTER__ value has been bumped, remember it. 1250 if (PP.getCounterValue() != 0) { 1251 Record.push_back(PP.getCounterValue()); 1252 Stream.EmitRecord(PP_COUNTER_VALUE, Record); 1253 Record.clear(); 1254 } 1255 1256 // Enter the preprocessor block. 1257 Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3); 1258 1259 // If the AST file contains __DATE__ or __TIME__ emit a warning about this. 1260 // FIXME: use diagnostics subsystem for localization etc. 1261 if (PP.SawDateOrTime()) 1262 fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n"); 1263 1264 1265 // Loop over all the macro definitions that are live at the end of the file, 1266 // emitting each to the PP section. 1267 PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); 1268 unsigned InclusionAbbrev = 0; 1269 if (PPRec) { 1270 using namespace llvm; 1271 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1272 Abbrev->Add(BitCodeAbbrevOp(PP_INCLUSION_DIRECTIVE)); 1273 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index 1274 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location 1275 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location 1276 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length 1277 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes 1278 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind 1279 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1280 InclusionAbbrev = Stream.EmitAbbrev(Abbrev); 1281 } 1282 1283 for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); 1284 I != E; ++I) { 1285 // FIXME: This emits macros in hash table order, we should do it in a stable 1286 // order so that output is reproducible. 1287 MacroInfo *MI = I->second; 1288 1289 // Don't emit builtin macros like __LINE__ to the AST file unless they have 1290 // been redefined by the header (in which case they are not isBuiltinMacro). 1291 // Also skip macros from a AST file if we're chaining. 1292 1293 // FIXME: There is a (probably minor) optimization we could do here, if 1294 // the macro comes from the original PCH but the identifier comes from a 1295 // chained PCH, by storing the offset into the original PCH rather than 1296 // writing the macro definition a second time. 1297 if (MI->isBuiltinMacro() || 1298 (Chain && I->first->isFromAST() && MI->isFromAST())) 1299 continue; 1300 1301 AddIdentifierRef(I->first, Record); 1302 MacroOffsets[I->first] = Stream.GetCurrentBitNo(); 1303 Record.push_back(MI->getDefinitionLoc().getRawEncoding()); 1304 Record.push_back(MI->isUsed()); 1305 1306 unsigned Code; 1307 if (MI->isObjectLike()) { 1308 Code = PP_MACRO_OBJECT_LIKE; 1309 } else { 1310 Code = PP_MACRO_FUNCTION_LIKE; 1311 1312 Record.push_back(MI->isC99Varargs()); 1313 Record.push_back(MI->isGNUVarargs()); 1314 Record.push_back(MI->getNumArgs()); 1315 for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end(); 1316 I != E; ++I) 1317 AddIdentifierRef(*I, Record); 1318 } 1319 1320 // If we have a detailed preprocessing record, record the macro definition 1321 // ID that corresponds to this macro. 1322 if (PPRec) 1323 Record.push_back(getMacroDefinitionID(PPRec->findMacroDefinition(MI))); 1324 1325 Stream.EmitRecord(Code, Record); 1326 Record.clear(); 1327 1328 // Emit the tokens array. 1329 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) { 1330 // Note that we know that the preprocessor does not have any annotation 1331 // tokens in it because they are created by the parser, and thus can't be 1332 // in a macro definition. 1333 const Token &Tok = MI->getReplacementToken(TokNo); 1334 1335 Record.push_back(Tok.getLocation().getRawEncoding()); 1336 Record.push_back(Tok.getLength()); 1337 1338 // FIXME: When reading literal tokens, reconstruct the literal pointer if 1339 // it is needed. 1340 AddIdentifierRef(Tok.getIdentifierInfo(), Record); 1341 1342 // FIXME: Should translate token kind to a stable encoding. 1343 Record.push_back(Tok.getKind()); 1344 // FIXME: Should translate token flags to a stable encoding. 1345 Record.push_back(Tok.getFlags()); 1346 1347 Stream.EmitRecord(PP_TOKEN, Record); 1348 Record.clear(); 1349 } 1350 ++NumMacros; 1351 } 1352 1353 // If the preprocessor has a preprocessing record, emit it. 1354 unsigned NumPreprocessingRecords = 0; 1355 if (PPRec) { 1356 unsigned IndexBase = Chain ? PPRec->getNumPreallocatedEntities() : 0; 1357 for (PreprocessingRecord::iterator E = PPRec->begin(Chain), 1358 EEnd = PPRec->end(Chain); 1359 E != EEnd; ++E) { 1360 Record.clear(); 1361 1362 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { 1363 // Record this macro definition's location. 1364 MacroID ID = getMacroDefinitionID(MD); 1365 1366 // Don't write the macro definition if it is from another AST file. 1367 if (ID < FirstMacroID) 1368 continue; 1369 1370 // Notify the serialization listener that we're serializing this entity. 1371 if (SerializationListener) 1372 SerializationListener->SerializedPreprocessedEntity(*E, 1373 Stream.GetCurrentBitNo()); 1374 1375 unsigned Position = ID - FirstMacroID; 1376 if (Position != MacroDefinitionOffsets.size()) { 1377 if (Position > MacroDefinitionOffsets.size()) 1378 MacroDefinitionOffsets.resize(Position + 1); 1379 1380 MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo(); 1381 } else 1382 MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); 1383 1384 Record.push_back(IndexBase + NumPreprocessingRecords++); 1385 Record.push_back(ID); 1386 AddSourceLocation(MD->getSourceRange().getBegin(), Record); 1387 AddSourceLocation(MD->getSourceRange().getEnd(), Record); 1388 AddIdentifierRef(MD->getName(), Record); 1389 AddSourceLocation(MD->getLocation(), Record); 1390 Stream.EmitRecord(PP_MACRO_DEFINITION, Record); 1391 continue; 1392 } 1393 1394 // Notify the serialization listener that we're serializing this entity. 1395 if (SerializationListener) 1396 SerializationListener->SerializedPreprocessedEntity(*E, 1397 Stream.GetCurrentBitNo()); 1398 1399 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { 1400 Record.push_back(IndexBase + NumPreprocessingRecords++); 1401 AddSourceLocation(MI->getSourceRange().getBegin(), Record); 1402 AddSourceLocation(MI->getSourceRange().getEnd(), Record); 1403 AddIdentifierRef(MI->getName(), Record); 1404 Record.push_back(getMacroDefinitionID(MI->getDefinition())); 1405 Stream.EmitRecord(PP_MACRO_INSTANTIATION, Record); 1406 continue; 1407 } 1408 1409 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { 1410 Record.push_back(PP_INCLUSION_DIRECTIVE); 1411 Record.push_back(IndexBase + NumPreprocessingRecords++); 1412 AddSourceLocation(ID->getSourceRange().getBegin(), Record); 1413 AddSourceLocation(ID->getSourceRange().getEnd(), Record); 1414 Record.push_back(ID->getFileName().size()); 1415 Record.push_back(ID->wasInQuotes()); 1416 Record.push_back(static_cast<unsigned>(ID->getKind())); 1417 llvm::SmallString<64> Buffer; 1418 Buffer += ID->getFileName(); 1419 Buffer += ID->getFile()->getName(); 1420 Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); 1421 continue; 1422 } 1423 1424 llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter"); 1425 } 1426 } 1427 1428 Stream.ExitBlock(); 1429 1430 // Write the offsets table for the preprocessing record. 1431 if (NumPreprocessingRecords > 0) { 1432 // Write the offsets table for identifier IDs. 1433 using namespace llvm; 1434 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1435 Abbrev->Add(BitCodeAbbrevOp(MACRO_DEFINITION_OFFSETS)); 1436 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of records 1437 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs 1438 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1439 unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1440 1441 Record.clear(); 1442 Record.push_back(MACRO_DEFINITION_OFFSETS); 1443 Record.push_back(NumPreprocessingRecords); 1444 Record.push_back(MacroDefinitionOffsets.size()); 1445 Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record, 1446 (const char *)data(MacroDefinitionOffsets), 1447 MacroDefinitionOffsets.size() * sizeof(uint32_t)); 1448 } 1449} 1450 1451void ASTWriter::WriteUserDiagnosticMappings(const Diagnostic &Diag) { 1452 RecordData Record; 1453 for (unsigned i = 0; i != diag::DIAG_UPPER_LIMIT; ++i) { 1454 diag::Mapping Map = Diag.getDiagnosticMappingInfo(i); 1455 if (Map & 0x8) { // user mapping. 1456 Record.push_back(i); 1457 Record.push_back(Map & 0x7); 1458 } 1459 } 1460 1461 if (!Record.empty()) 1462 Stream.EmitRecord(DIAG_USER_MAPPINGS, Record); 1463} 1464 1465//===----------------------------------------------------------------------===// 1466// Type Serialization 1467//===----------------------------------------------------------------------===// 1468 1469/// \brief Write the representation of a type to the AST stream. 1470void ASTWriter::WriteType(QualType T) { 1471 TypeIdx &Idx = TypeIdxs[T]; 1472 if (Idx.getIndex() == 0) // we haven't seen this type before. 1473 Idx = TypeIdx(NextTypeID++); 1474 1475 assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); 1476 1477 // Record the offset for this type. 1478 unsigned Index = Idx.getIndex() - FirstTypeID; 1479 if (TypeOffsets.size() == Index) 1480 TypeOffsets.push_back(Stream.GetCurrentBitNo()); 1481 else if (TypeOffsets.size() < Index) { 1482 TypeOffsets.resize(Index + 1); 1483 TypeOffsets[Index] = Stream.GetCurrentBitNo(); 1484 } 1485 1486 RecordData Record; 1487 1488 // Emit the type's representation. 1489 ASTTypeWriter W(*this, Record); 1490 1491 if (T.hasLocalNonFastQualifiers()) { 1492 Qualifiers Qs = T.getLocalQualifiers(); 1493 AddTypeRef(T.getLocalUnqualifiedType(), Record); 1494 Record.push_back(Qs.getAsOpaqueValue()); 1495 W.Code = TYPE_EXT_QUAL; 1496 } else { 1497 switch (T->getTypeClass()) { 1498 // For all of the concrete, non-dependent types, call the 1499 // appropriate visitor function. 1500#define TYPE(Class, Base) \ 1501 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break; 1502#define ABSTRACT_TYPE(Class, Base) 1503#include "clang/AST/TypeNodes.def" 1504 } 1505 } 1506 1507 // Emit the serialized record. 1508 Stream.EmitRecord(W.Code, Record); 1509 1510 // Flush any expressions that were written as part of this type. 1511 FlushStmts(); 1512} 1513 1514//===----------------------------------------------------------------------===// 1515// Declaration Serialization 1516//===----------------------------------------------------------------------===// 1517 1518/// \brief Write the block containing all of the declaration IDs 1519/// lexically declared within the given DeclContext. 1520/// 1521/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the 1522/// bistream, or 0 if no block was written. 1523uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, 1524 DeclContext *DC) { 1525 if (DC->decls_empty()) 1526 return 0; 1527 1528 uint64_t Offset = Stream.GetCurrentBitNo(); 1529 RecordData Record; 1530 Record.push_back(DECL_CONTEXT_LEXICAL); 1531 llvm::SmallVector<KindDeclIDPair, 64> Decls; 1532 for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); 1533 D != DEnd; ++D) 1534 Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D))); 1535 1536 ++NumLexicalDeclContexts; 1537 Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, 1538 reinterpret_cast<char*>(Decls.data()), 1539 Decls.size() * sizeof(KindDeclIDPair)); 1540 return Offset; 1541} 1542 1543void ASTWriter::WriteTypeDeclOffsets() { 1544 using namespace llvm; 1545 RecordData Record; 1546 1547 // Write the type offsets array 1548 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1549 Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET)); 1550 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types 1551 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block 1552 unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1553 Record.clear(); 1554 Record.push_back(TYPE_OFFSET); 1555 Record.push_back(TypeOffsets.size()); 1556 Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, 1557 (const char *)data(TypeOffsets), 1558 TypeOffsets.size() * sizeof(TypeOffsets[0])); 1559 1560 // Write the declaration offsets array 1561 Abbrev = new BitCodeAbbrev(); 1562 Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); 1563 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations 1564 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block 1565 unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1566 Record.clear(); 1567 Record.push_back(DECL_OFFSET); 1568 Record.push_back(DeclOffsets.size()); 1569 Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, 1570 (const char *)data(DeclOffsets), 1571 DeclOffsets.size() * sizeof(DeclOffsets[0])); 1572} 1573 1574//===----------------------------------------------------------------------===// 1575// Global Method Pool and Selector Serialization 1576//===----------------------------------------------------------------------===// 1577 1578namespace { 1579// Trait used for the on-disk hash table used in the method pool. 1580class ASTMethodPoolTrait { 1581 ASTWriter &Writer; 1582 1583public: 1584 typedef Selector key_type; 1585 typedef key_type key_type_ref; 1586 1587 struct data_type { 1588 SelectorID ID; 1589 ObjCMethodList Instance, Factory; 1590 }; 1591 typedef const data_type& data_type_ref; 1592 1593 explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { } 1594 1595 static unsigned ComputeHash(Selector Sel) { 1596 return serialization::ComputeHash(Sel); 1597 } 1598 1599 std::pair<unsigned,unsigned> 1600 EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel, 1601 data_type_ref Methods) { 1602 unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4); 1603 clang::io::Emit16(Out, KeyLen); 1604 unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts 1605 for (const ObjCMethodList *Method = &Methods.Instance; Method; 1606 Method = Method->Next) 1607 if (Method->Method) 1608 DataLen += 4; 1609 for (const ObjCMethodList *Method = &Methods.Factory; Method; 1610 Method = Method->Next) 1611 if (Method->Method) 1612 DataLen += 4; 1613 clang::io::Emit16(Out, DataLen); 1614 return std::make_pair(KeyLen, DataLen); 1615 } 1616 1617 void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) { 1618 uint64_t Start = Out.tell(); 1619 assert((Start >> 32) == 0 && "Selector key offset too large"); 1620 Writer.SetSelectorOffset(Sel, Start); 1621 unsigned N = Sel.getNumArgs(); 1622 clang::io::Emit16(Out, N); 1623 if (N == 0) 1624 N = 1; 1625 for (unsigned I = 0; I != N; ++I) 1626 clang::io::Emit32(Out, 1627 Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I))); 1628 } 1629 1630 void EmitData(llvm::raw_ostream& Out, key_type_ref, 1631 data_type_ref Methods, unsigned DataLen) { 1632 uint64_t Start = Out.tell(); (void)Start; 1633 clang::io::Emit32(Out, Methods.ID); 1634 unsigned NumInstanceMethods = 0; 1635 for (const ObjCMethodList *Method = &Methods.Instance; Method; 1636 Method = Method->Next) 1637 if (Method->Method) 1638 ++NumInstanceMethods; 1639 1640 unsigned NumFactoryMethods = 0; 1641 for (const ObjCMethodList *Method = &Methods.Factory; Method; 1642 Method = Method->Next) 1643 if (Method->Method) 1644 ++NumFactoryMethods; 1645 1646 clang::io::Emit16(Out, NumInstanceMethods); 1647 clang::io::Emit16(Out, NumFactoryMethods); 1648 for (const ObjCMethodList *Method = &Methods.Instance; Method; 1649 Method = Method->Next) 1650 if (Method->Method) 1651 clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 1652 for (const ObjCMethodList *Method = &Methods.Factory; Method; 1653 Method = Method->Next) 1654 if (Method->Method) 1655 clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 1656 1657 assert(Out.tell() - Start == DataLen && "Data length is wrong"); 1658 } 1659}; 1660} // end anonymous namespace 1661 1662/// \brief Write ObjC data: selectors and the method pool. 1663/// 1664/// The method pool contains both instance and factory methods, stored 1665/// in an on-disk hash table indexed by the selector. The hash table also 1666/// contains an empty entry for every other selector known to Sema. 1667void ASTWriter::WriteSelectors(Sema &SemaRef) { 1668 using namespace llvm; 1669 1670 // Do we have to do anything at all? 1671 if (SemaRef.MethodPool.empty() && SelectorIDs.empty()) 1672 return; 1673 unsigned NumTableEntries = 0; 1674 // Create and write out the blob that contains selectors and the method pool. 1675 { 1676 OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator; 1677 ASTMethodPoolTrait Trait(*this); 1678 1679 // Create the on-disk hash table representation. We walk through every 1680 // selector we've seen and look it up in the method pool. 1681 SelectorOffsets.resize(NextSelectorID - FirstSelectorID); 1682 for (llvm::DenseMap<Selector, SelectorID>::iterator 1683 I = SelectorIDs.begin(), E = SelectorIDs.end(); 1684 I != E; ++I) { 1685 Selector S = I->first; 1686 Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); 1687 ASTMethodPoolTrait::data_type Data = { 1688 I->second, 1689 ObjCMethodList(), 1690 ObjCMethodList() 1691 }; 1692 if (F != SemaRef.MethodPool.end()) { 1693 Data.Instance = F->second.first; 1694 Data.Factory = F->second.second; 1695 } 1696 // Only write this selector if it's not in an existing AST or something 1697 // changed. 1698 if (Chain && I->second < FirstSelectorID) { 1699 // Selector already exists. Did it change? 1700 bool changed = false; 1701 for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method; 1702 M = M->Next) { 1703 if (M->Method->getPCHLevel() == 0) 1704 changed = true; 1705 } 1706 for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method; 1707 M = M->Next) { 1708 if (M->Method->getPCHLevel() == 0) 1709 changed = true; 1710 } 1711 if (!changed) 1712 continue; 1713 } else if (Data.Instance.Method || Data.Factory.Method) { 1714 // A new method pool entry. 1715 ++NumTableEntries; 1716 } 1717 Generator.insert(S, Data, Trait); 1718 } 1719 1720 // Create the on-disk hash table in a buffer. 1721 llvm::SmallString<4096> MethodPool; 1722 uint32_t BucketOffset; 1723 { 1724 ASTMethodPoolTrait Trait(*this); 1725 llvm::raw_svector_ostream Out(MethodPool); 1726 // Make sure that no bucket is at offset 0 1727 clang::io::Emit32(Out, 0); 1728 BucketOffset = Generator.Emit(Out, Trait); 1729 } 1730 1731 // Create a blob abbreviation 1732 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1733 Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL)); 1734 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1735 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1736 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1737 unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev); 1738 1739 // Write the method pool 1740 RecordData Record; 1741 Record.push_back(METHOD_POOL); 1742 Record.push_back(BucketOffset); 1743 Record.push_back(NumTableEntries); 1744 Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str()); 1745 1746 // Create a blob abbreviation for the selector table offsets. 1747 Abbrev = new BitCodeAbbrev(); 1748 Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS)); 1749 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size 1750 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1751 unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1752 1753 // Write the selector offsets table. 1754 Record.clear(); 1755 Record.push_back(SELECTOR_OFFSETS); 1756 Record.push_back(SelectorOffsets.size()); 1757 Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, 1758 (const char *)data(SelectorOffsets), 1759 SelectorOffsets.size() * 4); 1760 } 1761} 1762 1763/// \brief Write the selectors referenced in @selector expression into AST file. 1764void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { 1765 using namespace llvm; 1766 if (SemaRef.ReferencedSelectors.empty()) 1767 return; 1768 1769 RecordData Record; 1770 1771 // Note: this writes out all references even for a dependent AST. But it is 1772 // very tricky to fix, and given that @selector shouldn't really appear in 1773 // headers, probably not worth it. It's not a correctness issue. 1774 for (DenseMap<Selector, SourceLocation>::iterator S = 1775 SemaRef.ReferencedSelectors.begin(), 1776 E = SemaRef.ReferencedSelectors.end(); S != E; ++S) { 1777 Selector Sel = (*S).first; 1778 SourceLocation Loc = (*S).second; 1779 AddSelectorRef(Sel, Record); 1780 AddSourceLocation(Loc, Record); 1781 } 1782 Stream.EmitRecord(REFERENCED_SELECTOR_POOL, Record); 1783} 1784 1785//===----------------------------------------------------------------------===// 1786// Identifier Table Serialization 1787//===----------------------------------------------------------------------===// 1788 1789namespace { 1790class ASTIdentifierTableTrait { 1791 ASTWriter &Writer; 1792 Preprocessor &PP; 1793 1794 /// \brief Determines whether this is an "interesting" identifier 1795 /// that needs a full IdentifierInfo structure written into the hash 1796 /// table. 1797 static bool isInterestingIdentifier(const IdentifierInfo *II) { 1798 return II->isPoisoned() || 1799 II->isExtensionToken() || 1800 II->hasMacroDefinition() || 1801 II->getObjCOrBuiltinID() || 1802 II->getFETokenInfo<void>(); 1803 } 1804 1805public: 1806 typedef const IdentifierInfo* key_type; 1807 typedef key_type key_type_ref; 1808 1809 typedef IdentID data_type; 1810 typedef data_type data_type_ref; 1811 1812 ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP) 1813 : Writer(Writer), PP(PP) { } 1814 1815 static unsigned ComputeHash(const IdentifierInfo* II) { 1816 return llvm::HashString(II->getName()); 1817 } 1818 1819 std::pair<unsigned,unsigned> 1820 EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II, 1821 IdentID ID) { 1822 unsigned KeyLen = II->getLength() + 1; 1823 unsigned DataLen = 4; // 4 bytes for the persistent ID << 1 1824 if (isInterestingIdentifier(II)) { 1825 DataLen += 2; // 2 bytes for builtin ID, flags 1826 if (II->hasMacroDefinition() && 1827 !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro()) 1828 DataLen += 4; 1829 for (IdentifierResolver::iterator D = IdentifierResolver::begin(II), 1830 DEnd = IdentifierResolver::end(); 1831 D != DEnd; ++D) 1832 DataLen += sizeof(DeclID); 1833 } 1834 clang::io::Emit16(Out, DataLen); 1835 // We emit the key length after the data length so that every 1836 // string is preceded by a 16-bit length. This matches the PTH 1837 // format for storing identifiers. 1838 clang::io::Emit16(Out, KeyLen); 1839 return std::make_pair(KeyLen, DataLen); 1840 } 1841 1842 void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II, 1843 unsigned KeyLen) { 1844 // Record the location of the key data. This is used when generating 1845 // the mapping from persistent IDs to strings. 1846 Writer.SetIdentifierOffset(II, Out.tell()); 1847 Out.write(II->getNameStart(), KeyLen); 1848 } 1849 1850 void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II, 1851 IdentID ID, unsigned) { 1852 if (!isInterestingIdentifier(II)) { 1853 clang::io::Emit32(Out, ID << 1); 1854 return; 1855 } 1856 1857 clang::io::Emit32(Out, (ID << 1) | 0x01); 1858 uint32_t Bits = 0; 1859 bool hasMacroDefinition = 1860 II->hasMacroDefinition() && 1861 !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro(); 1862 Bits = (uint32_t)II->getObjCOrBuiltinID(); 1863 Bits = (Bits << 1) | unsigned(hasMacroDefinition); 1864 Bits = (Bits << 1) | unsigned(II->isExtensionToken()); 1865 Bits = (Bits << 1) | unsigned(II->isPoisoned()); 1866 Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier()); 1867 Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword()); 1868 clang::io::Emit16(Out, Bits); 1869 1870 if (hasMacroDefinition) 1871 clang::io::Emit32(Out, Writer.getMacroOffset(II)); 1872 1873 // Emit the declaration IDs in reverse order, because the 1874 // IdentifierResolver provides the declarations as they would be 1875 // visible (e.g., the function "stat" would come before the struct 1876 // "stat"), but IdentifierResolver::AddDeclToIdentifierChain() 1877 // adds declarations to the end of the list (so we need to see the 1878 // struct "status" before the function "status"). 1879 // Only emit declarations that aren't from a chained PCH, though. 1880 llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II), 1881 IdentifierResolver::end()); 1882 for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(), 1883 DEnd = Decls.rend(); 1884 D != DEnd; ++D) 1885 clang::io::Emit32(Out, Writer.getDeclID(*D)); 1886 } 1887}; 1888} // end anonymous namespace 1889 1890/// \brief Write the identifier table into the AST file. 1891/// 1892/// The identifier table consists of a blob containing string data 1893/// (the actual identifiers themselves) and a separate "offsets" index 1894/// that maps identifier IDs to locations within the blob. 1895void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { 1896 using namespace llvm; 1897 1898 // Create and write out the blob that contains the identifier 1899 // strings. 1900 { 1901 OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; 1902 ASTIdentifierTableTrait Trait(*this, PP); 1903 1904 // Look for any identifiers that were named while processing the 1905 // headers, but are otherwise not needed. We add these to the hash 1906 // table to enable checking of the predefines buffer in the case 1907 // where the user adds new macro definitions when building the AST 1908 // file. 1909 for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(), 1910 IDEnd = PP.getIdentifierTable().end(); 1911 ID != IDEnd; ++ID) 1912 getIdentifierRef(ID->second); 1913 1914 // Create the on-disk hash table representation. We only store offsets 1915 // for identifiers that appear here for the first time. 1916 IdentifierOffsets.resize(NextIdentID - FirstIdentID); 1917 for (llvm::DenseMap<const IdentifierInfo *, IdentID>::iterator 1918 ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end(); 1919 ID != IDEnd; ++ID) { 1920 assert(ID->first && "NULL identifier in identifier table"); 1921 if (!Chain || !ID->first->isFromAST()) 1922 Generator.insert(ID->first, ID->second, Trait); 1923 } 1924 1925 // Create the on-disk hash table in a buffer. 1926 llvm::SmallString<4096> IdentifierTable; 1927 uint32_t BucketOffset; 1928 { 1929 ASTIdentifierTableTrait Trait(*this, PP); 1930 llvm::raw_svector_ostream Out(IdentifierTable); 1931 // Make sure that no bucket is at offset 0 1932 clang::io::Emit32(Out, 0); 1933 BucketOffset = Generator.Emit(Out, Trait); 1934 } 1935 1936 // Create a blob abbreviation 1937 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1938 Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE)); 1939 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1940 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1941 unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev); 1942 1943 // Write the identifier table 1944 RecordData Record; 1945 Record.push_back(IDENTIFIER_TABLE); 1946 Record.push_back(BucketOffset); 1947 Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str()); 1948 } 1949 1950 // Write the offsets table for identifier IDs. 1951 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1952 Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET)); 1953 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers 1954 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1955 unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1956 1957 RecordData Record; 1958 Record.push_back(IDENTIFIER_OFFSET); 1959 Record.push_back(IdentifierOffsets.size()); 1960 Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, 1961 (const char *)data(IdentifierOffsets), 1962 IdentifierOffsets.size() * sizeof(uint32_t)); 1963} 1964 1965//===----------------------------------------------------------------------===// 1966// DeclContext's Name Lookup Table Serialization 1967//===----------------------------------------------------------------------===// 1968 1969namespace { 1970// Trait used for the on-disk hash table used in the method pool. 1971class ASTDeclContextNameLookupTrait { 1972 ASTWriter &Writer; 1973 1974public: 1975 typedef DeclarationName key_type; 1976 typedef key_type key_type_ref; 1977 1978 typedef DeclContext::lookup_result data_type; 1979 typedef const data_type& data_type_ref; 1980 1981 explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { } 1982 1983 unsigned ComputeHash(DeclarationName Name) { 1984 llvm::FoldingSetNodeID ID; 1985 ID.AddInteger(Name.getNameKind()); 1986 1987 switch (Name.getNameKind()) { 1988 case DeclarationName::Identifier: 1989 ID.AddString(Name.getAsIdentifierInfo()->getName()); 1990 break; 1991 case DeclarationName::ObjCZeroArgSelector: 1992 case DeclarationName::ObjCOneArgSelector: 1993 case DeclarationName::ObjCMultiArgSelector: 1994 ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector())); 1995 break; 1996 case DeclarationName::CXXConstructorName: 1997 case DeclarationName::CXXDestructorName: 1998 case DeclarationName::CXXConversionFunctionName: 1999 ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType())); 2000 break; 2001 case DeclarationName::CXXOperatorName: 2002 ID.AddInteger(Name.getCXXOverloadedOperator()); 2003 break; 2004 case DeclarationName::CXXLiteralOperatorName: 2005 ID.AddString(Name.getCXXLiteralIdentifier()->getName()); 2006 case DeclarationName::CXXUsingDirective: 2007 break; 2008 } 2009 2010 return ID.ComputeHash(); 2011 } 2012 2013 std::pair<unsigned,unsigned> 2014 EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name, 2015 data_type_ref Lookup) { 2016 unsigned KeyLen = 1; 2017 switch (Name.getNameKind()) { 2018 case DeclarationName::Identifier: 2019 case DeclarationName::ObjCZeroArgSelector: 2020 case DeclarationName::ObjCOneArgSelector: 2021 case DeclarationName::ObjCMultiArgSelector: 2022 case DeclarationName::CXXConstructorName: 2023 case DeclarationName::CXXDestructorName: 2024 case DeclarationName::CXXConversionFunctionName: 2025 case DeclarationName::CXXLiteralOperatorName: 2026 KeyLen += 4; 2027 break; 2028 case DeclarationName::CXXOperatorName: 2029 KeyLen += 1; 2030 break; 2031 case DeclarationName::CXXUsingDirective: 2032 break; 2033 } 2034 clang::io::Emit16(Out, KeyLen); 2035 2036 // 2 bytes for num of decls and 4 for each DeclID. 2037 unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first); 2038 clang::io::Emit16(Out, DataLen); 2039 2040 return std::make_pair(KeyLen, DataLen); 2041 } 2042 2043 void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) { 2044 using namespace clang::io; 2045 2046 assert(Name.getNameKind() < 0x100 && "Invalid name kind ?"); 2047 Emit8(Out, Name.getNameKind()); 2048 switch (Name.getNameKind()) { 2049 case DeclarationName::Identifier: 2050 Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo())); 2051 break; 2052 case DeclarationName::ObjCZeroArgSelector: 2053 case DeclarationName::ObjCOneArgSelector: 2054 case DeclarationName::ObjCMultiArgSelector: 2055 Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector())); 2056 break; 2057 case DeclarationName::CXXConstructorName: 2058 case DeclarationName::CXXDestructorName: 2059 case DeclarationName::CXXConversionFunctionName: 2060 Emit32(Out, Writer.getTypeID(Name.getCXXNameType())); 2061 break; 2062 case DeclarationName::CXXOperatorName: 2063 assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?"); 2064 Emit8(Out, Name.getCXXOverloadedOperator()); 2065 break; 2066 case DeclarationName::CXXLiteralOperatorName: 2067 Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier())); 2068 break; 2069 case DeclarationName::CXXUsingDirective: 2070 break; 2071 } 2072 } 2073 2074 void EmitData(llvm::raw_ostream& Out, key_type_ref, 2075 data_type Lookup, unsigned DataLen) { 2076 uint64_t Start = Out.tell(); (void)Start; 2077 clang::io::Emit16(Out, Lookup.second - Lookup.first); 2078 for (; Lookup.first != Lookup.second; ++Lookup.first) 2079 clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first)); 2080 2081 assert(Out.tell() - Start == DataLen && "Data length is wrong"); 2082 } 2083}; 2084} // end anonymous namespace 2085 2086/// \brief Write the block containing all of the declaration IDs 2087/// visible from the given DeclContext. 2088/// 2089/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the 2090/// bitstream, or 0 if no block was written. 2091uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, 2092 DeclContext *DC) { 2093 if (DC->getPrimaryContext() != DC) 2094 return 0; 2095 2096 // Since there is no name lookup into functions or methods, don't bother to 2097 // build a visible-declarations table for these entities. 2098 if (DC->isFunctionOrMethod()) 2099 return 0; 2100 2101 // If not in C++, we perform name lookup for the translation unit via the 2102 // IdentifierInfo chains, don't bother to build a visible-declarations table. 2103 // FIXME: In C++ we need the visible declarations in order to "see" the 2104 // friend declarations, is there a way to do this without writing the table ? 2105 if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) 2106 return 0; 2107 2108 // Force the DeclContext to build a its name-lookup table. 2109 if (DC->hasExternalVisibleStorage()) 2110 DC->MaterializeVisibleDeclsFromExternalStorage(); 2111 else 2112 DC->lookup(DeclarationName()); 2113 2114 // Serialize the contents of the mapping used for lookup. Note that, 2115 // although we have two very different code paths, the serialized 2116 // representation is the same for both cases: a declaration name, 2117 // followed by a size, followed by references to the visible 2118 // declarations that have that name. 2119 uint64_t Offset = Stream.GetCurrentBitNo(); 2120 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); 2121 if (!Map || Map->empty()) 2122 return 0; 2123 2124 OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; 2125 ASTDeclContextNameLookupTrait Trait(*this); 2126 2127 // Create the on-disk hash table representation. 2128 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); 2129 D != DEnd; ++D) { 2130 DeclarationName Name = D->first; 2131 DeclContext::lookup_result Result = D->second.getLookupResult(); 2132 Generator.insert(Name, Result, Trait); 2133 } 2134 2135 // Create the on-disk hash table in a buffer. 2136 llvm::SmallString<4096> LookupTable; 2137 uint32_t BucketOffset; 2138 { 2139 llvm::raw_svector_ostream Out(LookupTable); 2140 // Make sure that no bucket is at offset 0 2141 clang::io::Emit32(Out, 0); 2142 BucketOffset = Generator.Emit(Out, Trait); 2143 } 2144 2145 // Write the lookup table 2146 RecordData Record; 2147 Record.push_back(DECL_CONTEXT_VISIBLE); 2148 Record.push_back(BucketOffset); 2149 Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, 2150 LookupTable.str()); 2151 2152 Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); 2153 ++NumVisibleDeclContexts; 2154 return Offset; 2155} 2156 2157/// \brief Write an UPDATE_VISIBLE block for the given context. 2158/// 2159/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing 2160/// DeclContext in a dependent AST file. As such, they only exist for the TU 2161/// (in C++) and for namespaces. 2162void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { 2163 // Make the context build its lookup table, but don't make it load external 2164 // decls. 2165 DC->lookup(DeclarationName()); 2166 2167 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); 2168 if (!Map || Map->empty()) 2169 return; 2170 2171 OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; 2172 ASTDeclContextNameLookupTrait Trait(*this); 2173 2174 // Create the hash table. 2175 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); 2176 D != DEnd; ++D) { 2177 DeclarationName Name = D->first; 2178 DeclContext::lookup_result Result = D->second.getLookupResult(); 2179 // For any name that appears in this table, the results are complete, i.e. 2180 // they overwrite results from previous PCHs. Merging is always a mess. 2181 Generator.insert(Name, Result, Trait); 2182 } 2183 2184 // Create the on-disk hash table in a buffer. 2185 llvm::SmallString<4096> LookupTable; 2186 uint32_t BucketOffset; 2187 { 2188 llvm::raw_svector_ostream Out(LookupTable); 2189 // Make sure that no bucket is at offset 0 2190 clang::io::Emit32(Out, 0); 2191 BucketOffset = Generator.Emit(Out, Trait); 2192 } 2193 2194 // Write the lookup table 2195 RecordData Record; 2196 Record.push_back(UPDATE_VISIBLE); 2197 Record.push_back(getDeclID(cast<Decl>(DC))); 2198 Record.push_back(BucketOffset); 2199 Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); 2200} 2201 2202//===----------------------------------------------------------------------===// 2203// General Serialization Routines 2204//===----------------------------------------------------------------------===// 2205 2206/// \brief Write a record containing the given attributes. 2207void ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) { 2208 Record.push_back(Attrs.size()); 2209 for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){ 2210 const Attr * A = *i; 2211 Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs 2212 AddSourceLocation(A->getLocation(), Record); 2213 Record.push_back(A->isInherited()); 2214 2215#include "clang/Serialization/AttrPCHWrite.inc" 2216 2217 } 2218} 2219 2220void ASTWriter::AddString(llvm::StringRef Str, RecordDataImpl &Record) { 2221 Record.push_back(Str.size()); 2222 Record.insert(Record.end(), Str.begin(), Str.end()); 2223} 2224 2225/// \brief Note that the identifier II occurs at the given offset 2226/// within the identifier table. 2227void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { 2228 IdentID ID = IdentifierIDs[II]; 2229 // Only store offsets new to this AST file. Other identifier names are looked 2230 // up earlier in the chain and thus don't need an offset. 2231 if (ID >= FirstIdentID) 2232 IdentifierOffsets[ID - FirstIdentID] = Offset; 2233} 2234 2235/// \brief Note that the selector Sel occurs at the given offset 2236/// within the method pool/selector table. 2237void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { 2238 unsigned ID = SelectorIDs[Sel]; 2239 assert(ID && "Unknown selector"); 2240 // Don't record offsets for selectors that are also available in a different 2241 // file. 2242 if (ID < FirstSelectorID) 2243 return; 2244 SelectorOffsets[ID - FirstSelectorID] = Offset; 2245} 2246 2247ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) 2248 : Stream(Stream), Chain(0), SerializationListener(0), 2249 FirstDeclID(1), NextDeclID(FirstDeclID), 2250 FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), 2251 FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), 2252 NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID), 2253 CollectedStmts(&StmtsToEmit), 2254 NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), 2255 NumVisibleDeclContexts(0), FirstCXXBaseSpecifiersID(1), 2256 NextCXXBaseSpecifiersID(1) 2257{ 2258} 2259 2260void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2261 const char *isysroot) { 2262 // Emit the file header. 2263 Stream.Emit((unsigned)'C', 8); 2264 Stream.Emit((unsigned)'P', 8); 2265 Stream.Emit((unsigned)'C', 8); 2266 Stream.Emit((unsigned)'H', 8); 2267 2268 WriteBlockInfoBlock(); 2269 2270 if (Chain) 2271 WriteASTChain(SemaRef, StatCalls, isysroot); 2272 else 2273 WriteASTCore(SemaRef, StatCalls, isysroot); 2274} 2275 2276void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2277 const char *isysroot) { 2278 using namespace llvm; 2279 2280 ASTContext &Context = SemaRef.Context; 2281 Preprocessor &PP = SemaRef.PP; 2282 2283 // The translation unit is the first declaration we'll emit. 2284 DeclIDs[Context.getTranslationUnitDecl()] = 1; 2285 ++NextDeclID; 2286 DeclTypesToEmit.push(Context.getTranslationUnitDecl()); 2287 2288 // Make sure that we emit IdentifierInfos (and any attached 2289 // declarations) for builtins. 2290 { 2291 IdentifierTable &Table = PP.getIdentifierTable(); 2292 llvm::SmallVector<const char *, 32> BuiltinNames; 2293 Context.BuiltinInfo.GetBuiltinNames(BuiltinNames, 2294 Context.getLangOptions().NoBuiltin); 2295 for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I) 2296 getIdentifierRef(&Table.get(BuiltinNames[I])); 2297 } 2298 2299 // Build a record containing all of the tentative definitions in this file, in 2300 // TentativeDefinitions order. Generally, this record will be empty for 2301 // headers. 2302 RecordData TentativeDefinitions; 2303 for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 2304 AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 2305 } 2306 2307 // Build a record containing all of the file scoped decls in this file. 2308 RecordData UnusedFileScopedDecls; 2309 for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) 2310 AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 2311 2312 RecordData WeakUndeclaredIdentifiers; 2313 if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 2314 WeakUndeclaredIdentifiers.push_back( 2315 SemaRef.WeakUndeclaredIdentifiers.size()); 2316 for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 2317 I = SemaRef.WeakUndeclaredIdentifiers.begin(), 2318 E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 2319 AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 2320 AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 2321 AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 2322 WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 2323 } 2324 } 2325 2326 // Build a record containing all of the locally-scoped external 2327 // declarations in this header file. Generally, this record will be 2328 // empty. 2329 RecordData LocallyScopedExternalDecls; 2330 // FIXME: This is filling in the AST file in densemap order which is 2331 // nondeterminstic! 2332 for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 2333 TD = SemaRef.LocallyScopedExternalDecls.begin(), 2334 TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 2335 TD != TDEnd; ++TD) 2336 AddDeclRef(TD->second, LocallyScopedExternalDecls); 2337 2338 // Build a record containing all of the ext_vector declarations. 2339 RecordData ExtVectorDecls; 2340 for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) 2341 AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 2342 2343 // Build a record containing all of the VTable uses information. 2344 RecordData VTableUses; 2345 if (!SemaRef.VTableUses.empty()) { 2346 VTableUses.push_back(SemaRef.VTableUses.size()); 2347 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 2348 AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 2349 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 2350 VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 2351 } 2352 } 2353 2354 // Build a record containing all of dynamic classes declarations. 2355 RecordData DynamicClasses; 2356 for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 2357 AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 2358 2359 // Build a record containing all of pending implicit instantiations. 2360 RecordData PendingInstantiations; 2361 for (std::deque<Sema::PendingImplicitInstantiation>::iterator 2362 I = SemaRef.PendingInstantiations.begin(), 2363 N = SemaRef.PendingInstantiations.end(); I != N; ++I) { 2364 AddDeclRef(I->first, PendingInstantiations); 2365 AddSourceLocation(I->second, PendingInstantiations); 2366 } 2367 assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 2368 "There are local ones at end of translation unit!"); 2369 2370 // Build a record containing some declaration references. 2371 RecordData SemaDeclRefs; 2372 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 2373 AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 2374 AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 2375 } 2376 2377 // Write the remaining AST contents. 2378 RecordData Record; 2379 Stream.EnterSubblock(AST_BLOCK_ID, 5); 2380 WriteMetadata(Context, isysroot); 2381 WriteLanguageOptions(Context.getLangOptions()); 2382 if (StatCalls && !isysroot) 2383 WriteStatCache(*StatCalls); 2384 WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2385 // Write the record of special types. 2386 Record.clear(); 2387 2388 AddTypeRef(Context.getBuiltinVaListType(), Record); 2389 AddTypeRef(Context.getObjCIdType(), Record); 2390 AddTypeRef(Context.getObjCSelType(), Record); 2391 AddTypeRef(Context.getObjCProtoType(), Record); 2392 AddTypeRef(Context.getObjCClassType(), Record); 2393 AddTypeRef(Context.getRawCFConstantStringType(), Record); 2394 AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record); 2395 AddTypeRef(Context.getFILEType(), Record); 2396 AddTypeRef(Context.getjmp_bufType(), Record); 2397 AddTypeRef(Context.getsigjmp_bufType(), Record); 2398 AddTypeRef(Context.ObjCIdRedefinitionType, Record); 2399 AddTypeRef(Context.ObjCClassRedefinitionType, Record); 2400 AddTypeRef(Context.getRawBlockdescriptorType(), Record); 2401 AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record); 2402 AddTypeRef(Context.ObjCSelRedefinitionType, Record); 2403 AddTypeRef(Context.getRawNSConstantStringType(), Record); 2404 Record.push_back(Context.isInt128Installed()); 2405 Stream.EmitRecord(SPECIAL_TYPES, Record); 2406 2407 // Keep writing types and declarations until all types and 2408 // declarations have been written. 2409 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3); 2410 WriteDeclsBlockAbbrevs(); 2411 while (!DeclTypesToEmit.empty()) { 2412 DeclOrType DOT = DeclTypesToEmit.front(); 2413 DeclTypesToEmit.pop(); 2414 if (DOT.isType()) 2415 WriteType(DOT.getType()); 2416 else 2417 WriteDecl(Context, DOT.getDecl()); 2418 } 2419 Stream.ExitBlock(); 2420 2421 WritePreprocessor(PP); 2422 WriteSelectors(SemaRef); 2423 WriteReferencedSelectorsPool(SemaRef); 2424 WriteIdentifierTable(PP); 2425 2426 WriteTypeDeclOffsets(); 2427 WriteUserDiagnosticMappings(Context.getDiagnostics()); 2428 2429 // Write the C++ base-specifier set offsets. 2430 if (!CXXBaseSpecifiersOffsets.empty()) { 2431 // Create a blob abbreviation for the C++ base specifiers offsets. 2432 using namespace llvm; 2433 2434 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 2435 Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS)); 2436 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size 2437 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2438 unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 2439 2440 // Write the selector offsets table. 2441 Record.clear(); 2442 Record.push_back(CXX_BASE_SPECIFIER_OFFSETS); 2443 Record.push_back(CXXBaseSpecifiersOffsets.size()); 2444 Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, 2445 (const char *)CXXBaseSpecifiersOffsets.data(), 2446 CXXBaseSpecifiersOffsets.size() * sizeof(uint32_t)); 2447 } 2448 2449 // Write the record containing external, unnamed definitions. 2450 if (!ExternalDefinitions.empty()) 2451 Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 2452 2453 // Write the record containing tentative definitions. 2454 if (!TentativeDefinitions.empty()) 2455 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 2456 2457 // Write the record containing unused file scoped decls. 2458 if (!UnusedFileScopedDecls.empty()) 2459 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 2460 2461 // Write the record containing weak undeclared identifiers. 2462 if (!WeakUndeclaredIdentifiers.empty()) 2463 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 2464 WeakUndeclaredIdentifiers); 2465 2466 // Write the record containing locally-scoped external definitions. 2467 if (!LocallyScopedExternalDecls.empty()) 2468 Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 2469 LocallyScopedExternalDecls); 2470 2471 // Write the record containing ext_vector type names. 2472 if (!ExtVectorDecls.empty()) 2473 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 2474 2475 // Write the record containing VTable uses information. 2476 if (!VTableUses.empty()) 2477 Stream.EmitRecord(VTABLE_USES, VTableUses); 2478 2479 // Write the record containing dynamic classes declarations. 2480 if (!DynamicClasses.empty()) 2481 Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 2482 2483 // Write the record containing pending implicit instantiations. 2484 if (!PendingInstantiations.empty()) 2485 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); 2486 2487 // Write the record containing declaration references of Sema. 2488 if (!SemaDeclRefs.empty()) 2489 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 2490 2491 // Some simple statistics 2492 Record.clear(); 2493 Record.push_back(NumStatements); 2494 Record.push_back(NumMacros); 2495 Record.push_back(NumLexicalDeclContexts); 2496 Record.push_back(NumVisibleDeclContexts); 2497 Stream.EmitRecord(STATISTICS, Record); 2498 Stream.ExitBlock(); 2499} 2500 2501void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2502 const char *isysroot) { 2503 using namespace llvm; 2504 2505 ASTContext &Context = SemaRef.Context; 2506 Preprocessor &PP = SemaRef.PP; 2507 2508 RecordData Record; 2509 Stream.EnterSubblock(AST_BLOCK_ID, 5); 2510 WriteMetadata(Context, isysroot); 2511 if (StatCalls && !isysroot) 2512 WriteStatCache(*StatCalls); 2513 // FIXME: Source manager block should only write new stuff, which could be 2514 // done by tracking the largest ID in the chain 2515 WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2516 2517 // The special types are in the chained PCH. 2518 2519 // We don't start with the translation unit, but with its decls that 2520 // don't come from the chained PCH. 2521 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); 2522 llvm::SmallVector<KindDeclIDPair, 64> NewGlobalDecls; 2523 for (DeclContext::decl_iterator I = TU->noload_decls_begin(), 2524 E = TU->noload_decls_end(); 2525 I != E; ++I) { 2526 if ((*I)->getPCHLevel() == 0) 2527 NewGlobalDecls.push_back(std::make_pair((*I)->getKind(), GetDeclRef(*I))); 2528 else if ((*I)->isChangedSinceDeserialization()) 2529 (void)GetDeclRef(*I); // Make sure it's written, but don't record it. 2530 } 2531 // We also need to write a lexical updates block for the TU. 2532 llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev(); 2533 Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); 2534 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 2535 unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abv); 2536 Record.clear(); 2537 Record.push_back(TU_UPDATE_LEXICAL); 2538 Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, 2539 reinterpret_cast<const char*>(NewGlobalDecls.data()), 2540 NewGlobalDecls.size() * sizeof(KindDeclIDPair)); 2541 // And a visible updates block for the DeclContexts. 2542 Abv = new llvm::BitCodeAbbrev(); 2543 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); 2544 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 2545 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); 2546 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 2547 UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); 2548 WriteDeclContextVisibleUpdate(TU); 2549 2550 // Build a record containing all of the new tentative definitions in this 2551 // file, in TentativeDefinitions order. 2552 RecordData TentativeDefinitions; 2553 for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 2554 if (SemaRef.TentativeDefinitions[i]->getPCHLevel() == 0) 2555 AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 2556 } 2557 2558 // Build a record containing all of the file scoped decls in this file. 2559 RecordData UnusedFileScopedDecls; 2560 for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) { 2561 if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0) 2562 AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 2563 } 2564 2565 // We write the entire table, overwriting the tables from the chain. 2566 RecordData WeakUndeclaredIdentifiers; 2567 if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 2568 WeakUndeclaredIdentifiers.push_back( 2569 SemaRef.WeakUndeclaredIdentifiers.size()); 2570 for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 2571 I = SemaRef.WeakUndeclaredIdentifiers.begin(), 2572 E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 2573 AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 2574 AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 2575 AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 2576 WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 2577 } 2578 } 2579 2580 // Build a record containing all of the locally-scoped external 2581 // declarations in this header file. Generally, this record will be 2582 // empty. 2583 RecordData LocallyScopedExternalDecls; 2584 // FIXME: This is filling in the AST file in densemap order which is 2585 // nondeterminstic! 2586 for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 2587 TD = SemaRef.LocallyScopedExternalDecls.begin(), 2588 TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 2589 TD != TDEnd; ++TD) { 2590 if (TD->second->getPCHLevel() == 0) 2591 AddDeclRef(TD->second, LocallyScopedExternalDecls); 2592 } 2593 2594 // Build a record containing all of the ext_vector declarations. 2595 RecordData ExtVectorDecls; 2596 for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) { 2597 if (SemaRef.ExtVectorDecls[I]->getPCHLevel() == 0) 2598 AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 2599 } 2600 2601 // Build a record containing all of the VTable uses information. 2602 // We write everything here, because it's too hard to determine whether 2603 // a use is new to this part. 2604 RecordData VTableUses; 2605 if (!SemaRef.VTableUses.empty()) { 2606 VTableUses.push_back(SemaRef.VTableUses.size()); 2607 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 2608 AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 2609 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 2610 VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 2611 } 2612 } 2613 2614 // Build a record containing all of dynamic classes declarations. 2615 RecordData DynamicClasses; 2616 for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 2617 if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0) 2618 AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 2619 2620 // Build a record containing all of pending implicit instantiations. 2621 RecordData PendingInstantiations; 2622 for (std::deque<Sema::PendingImplicitInstantiation>::iterator 2623 I = SemaRef.PendingInstantiations.begin(), 2624 N = SemaRef.PendingInstantiations.end(); I != N; ++I) { 2625 if (I->first->getPCHLevel() == 0) { 2626 AddDeclRef(I->first, PendingInstantiations); 2627 AddSourceLocation(I->second, PendingInstantiations); 2628 } 2629 } 2630 assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 2631 "There are local ones at end of translation unit!"); 2632 2633 // Build a record containing some declaration references. 2634 // It's not worth the effort to avoid duplication here. 2635 RecordData SemaDeclRefs; 2636 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 2637 AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 2638 AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 2639 } 2640 2641 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3); 2642 WriteDeclsBlockAbbrevs(); 2643 for (DeclsToRewriteTy::iterator 2644 I = DeclsToRewrite.begin(), E = DeclsToRewrite.end(); I != E; ++I) 2645 DeclTypesToEmit.push(const_cast<Decl*>(*I)); 2646 while (!DeclTypesToEmit.empty()) { 2647 DeclOrType DOT = DeclTypesToEmit.front(); 2648 DeclTypesToEmit.pop(); 2649 if (DOT.isType()) 2650 WriteType(DOT.getType()); 2651 else 2652 WriteDecl(Context, DOT.getDecl()); 2653 } 2654 Stream.ExitBlock(); 2655 2656 WritePreprocessor(PP); 2657 WriteSelectors(SemaRef); 2658 WriteReferencedSelectorsPool(SemaRef); 2659 WriteIdentifierTable(PP); 2660 WriteTypeDeclOffsets(); 2661 // FIXME: For chained PCH only write the new mappings (we currently 2662 // write all of them again). 2663 WriteUserDiagnosticMappings(Context.getDiagnostics()); 2664 2665 /// Build a record containing first declarations from a chained PCH and the 2666 /// most recent declarations in this AST that they point to. 2667 RecordData FirstLatestDeclIDs; 2668 for (FirstLatestDeclMap::iterator 2669 I = FirstLatestDecls.begin(), E = FirstLatestDecls.end(); I != E; ++I) { 2670 assert(I->first->getPCHLevel() > I->second->getPCHLevel() && 2671 "Expected first & second to be in different PCHs"); 2672 AddDeclRef(I->first, FirstLatestDeclIDs); 2673 AddDeclRef(I->second, FirstLatestDeclIDs); 2674 } 2675 if (!FirstLatestDeclIDs.empty()) 2676 Stream.EmitRecord(REDECLS_UPDATE_LATEST, FirstLatestDeclIDs); 2677 2678 // Write the record containing external, unnamed definitions. 2679 if (!ExternalDefinitions.empty()) 2680 Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 2681 2682 // Write the record containing tentative definitions. 2683 if (!TentativeDefinitions.empty()) 2684 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 2685 2686 // Write the record containing unused file scoped decls. 2687 if (!UnusedFileScopedDecls.empty()) 2688 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 2689 2690 // Write the record containing weak undeclared identifiers. 2691 if (!WeakUndeclaredIdentifiers.empty()) 2692 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 2693 WeakUndeclaredIdentifiers); 2694 2695 // Write the record containing locally-scoped external definitions. 2696 if (!LocallyScopedExternalDecls.empty()) 2697 Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 2698 LocallyScopedExternalDecls); 2699 2700 // Write the record containing ext_vector type names. 2701 if (!ExtVectorDecls.empty()) 2702 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 2703 2704 // Write the record containing VTable uses information. 2705 if (!VTableUses.empty()) 2706 Stream.EmitRecord(VTABLE_USES, VTableUses); 2707 2708 // Write the record containing dynamic classes declarations. 2709 if (!DynamicClasses.empty()) 2710 Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 2711 2712 // Write the record containing pending implicit instantiations. 2713 if (!PendingInstantiations.empty()) 2714 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); 2715 2716 // Write the record containing declaration references of Sema. 2717 if (!SemaDeclRefs.empty()) 2718 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 2719 2720 // Write the updates to DeclContexts. 2721 for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator 2722 I = UpdatedDeclContexts.begin(), 2723 E = UpdatedDeclContexts.end(); 2724 I != E; ++I) 2725 WriteDeclContextVisibleUpdate(*I); 2726 2727 WriteDeclUpdatesBlocks(); 2728 2729 Record.clear(); 2730 Record.push_back(NumStatements); 2731 Record.push_back(NumMacros); 2732 Record.push_back(NumLexicalDeclContexts); 2733 Record.push_back(NumVisibleDeclContexts); 2734 WriteDeclReplacementsBlock(); 2735 Stream.EmitRecord(STATISTICS, Record); 2736 Stream.ExitBlock(); 2737} 2738 2739void ASTWriter::WriteDeclUpdatesBlocks() { 2740 if (DeclUpdates.empty()) 2741 return; 2742 2743 RecordData OffsetsRecord; 2744 Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, 3); 2745 for (DeclUpdateMap::iterator 2746 I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) { 2747 const Decl *D = I->first; 2748 UpdateRecord &URec = I->second; 2749 2750 if (DeclsToRewrite.count(D)) 2751 continue; // The decl will be written completely,no need to store updates. 2752 2753 uint64_t Offset = Stream.GetCurrentBitNo(); 2754 Stream.EmitRecord(DECL_UPDATES, URec); 2755 2756 OffsetsRecord.push_back(GetDeclRef(D)); 2757 OffsetsRecord.push_back(Offset); 2758 } 2759 Stream.ExitBlock(); 2760 Stream.EmitRecord(DECL_UPDATE_OFFSETS, OffsetsRecord); 2761} 2762 2763void ASTWriter::WriteDeclReplacementsBlock() { 2764 if (ReplacedDecls.empty()) 2765 return; 2766 2767 RecordData Record; 2768 for (llvm::SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator 2769 I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) { 2770 Record.push_back(I->first); 2771 Record.push_back(I->second); 2772 } 2773 Stream.EmitRecord(DECL_REPLACEMENTS, Record); 2774} 2775 2776void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) { 2777 Record.push_back(Loc.getRawEncoding()); 2778} 2779 2780void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) { 2781 AddSourceLocation(Range.getBegin(), Record); 2782 AddSourceLocation(Range.getEnd(), Record); 2783} 2784 2785void ASTWriter::AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record) { 2786 Record.push_back(Value.getBitWidth()); 2787 const uint64_t *Words = Value.getRawData(); 2788 Record.append(Words, Words + Value.getNumWords()); 2789} 2790 2791void ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record) { 2792 Record.push_back(Value.isUnsigned()); 2793 AddAPInt(Value, Record); 2794} 2795 2796void ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record) { 2797 AddAPInt(Value.bitcastToAPInt(), Record); 2798} 2799 2800void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) { 2801 Record.push_back(getIdentifierRef(II)); 2802} 2803 2804IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) { 2805 if (II == 0) 2806 return 0; 2807 2808 IdentID &ID = IdentifierIDs[II]; 2809 if (ID == 0) 2810 ID = NextIdentID++; 2811 return ID; 2812} 2813 2814MacroID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) { 2815 if (MD == 0) 2816 return 0; 2817 2818 MacroID &ID = MacroDefinitions[MD]; 2819 if (ID == 0) 2820 ID = NextMacroID++; 2821 return ID; 2822} 2823 2824void ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) { 2825 Record.push_back(getSelectorRef(SelRef)); 2826} 2827 2828SelectorID ASTWriter::getSelectorRef(Selector Sel) { 2829 if (Sel.getAsOpaquePtr() == 0) { 2830 return 0; 2831 } 2832 2833 SelectorID &SID = SelectorIDs[Sel]; 2834 if (SID == 0 && Chain) { 2835 // This might trigger a ReadSelector callback, which will set the ID for 2836 // this selector. 2837 Chain->LoadSelector(Sel); 2838 } 2839 if (SID == 0) { 2840 SID = NextSelectorID++; 2841 } 2842 return SID; 2843} 2844 2845void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record) { 2846 AddDeclRef(Temp->getDestructor(), Record); 2847} 2848 2849void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, 2850 CXXBaseSpecifier const *BasesEnd, 2851 RecordDataImpl &Record) { 2852 assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded"); 2853 CXXBaseSpecifiersToWrite.push_back( 2854 QueuedCXXBaseSpecifiers(NextCXXBaseSpecifiersID, 2855 Bases, BasesEnd)); 2856 Record.push_back(NextCXXBaseSpecifiersID++); 2857} 2858 2859void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, 2860 const TemplateArgumentLocInfo &Arg, 2861 RecordDataImpl &Record) { 2862 switch (Kind) { 2863 case TemplateArgument::Expression: 2864 AddStmt(Arg.getAsExpr()); 2865 break; 2866 case TemplateArgument::Type: 2867 AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record); 2868 break; 2869 case TemplateArgument::Template: 2870 AddSourceRange(Arg.getTemplateQualifierRange(), Record); 2871 AddSourceLocation(Arg.getTemplateNameLoc(), Record); 2872 break; 2873 case TemplateArgument::Null: 2874 case TemplateArgument::Integral: 2875 case TemplateArgument::Declaration: 2876 case TemplateArgument::Pack: 2877 break; 2878 } 2879} 2880 2881void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, 2882 RecordDataImpl &Record) { 2883 AddTemplateArgument(Arg.getArgument(), Record); 2884 2885 if (Arg.getArgument().getKind() == TemplateArgument::Expression) { 2886 bool InfoHasSameExpr 2887 = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr(); 2888 Record.push_back(InfoHasSameExpr); 2889 if (InfoHasSameExpr) 2890 return; // Avoid storing the same expr twice. 2891 } 2892 AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(), 2893 Record); 2894} 2895 2896void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record) { 2897 if (TInfo == 0) { 2898 AddTypeRef(QualType(), Record); 2899 return; 2900 } 2901 2902 AddTypeRef(TInfo->getType(), Record); 2903 TypeLocWriter TLW(*this, Record); 2904 for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) 2905 TLW.Visit(TL); 2906} 2907 2908void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) { 2909 Record.push_back(GetOrCreateTypeID(T)); 2910} 2911 2912TypeID ASTWriter::GetOrCreateTypeID(QualType T) { 2913 return MakeTypeID(T, 2914 std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this)); 2915} 2916 2917TypeID ASTWriter::getTypeID(QualType T) const { 2918 return MakeTypeID(T, 2919 std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this)); 2920} 2921 2922TypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) { 2923 if (T.isNull()) 2924 return TypeIdx(); 2925 assert(!T.getLocalFastQualifiers()); 2926 2927 TypeIdx &Idx = TypeIdxs[T]; 2928 if (Idx.getIndex() == 0) { 2929 // We haven't seen this type before. Assign it a new ID and put it 2930 // into the queue of types to emit. 2931 Idx = TypeIdx(NextTypeID++); 2932 DeclTypesToEmit.push(T); 2933 } 2934 return Idx; 2935} 2936 2937TypeIdx ASTWriter::getTypeIdx(QualType T) const { 2938 if (T.isNull()) 2939 return TypeIdx(); 2940 assert(!T.getLocalFastQualifiers()); 2941 2942 TypeIdxMap::const_iterator I = TypeIdxs.find(T); 2943 assert(I != TypeIdxs.end() && "Type not emitted!"); 2944 return I->second; 2945} 2946 2947void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { 2948 Record.push_back(GetDeclRef(D)); 2949} 2950 2951DeclID ASTWriter::GetDeclRef(const Decl *D) { 2952 if (D == 0) { 2953 return 0; 2954 } 2955 assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer"); 2956 DeclID &ID = DeclIDs[D]; 2957 if (ID == 0) { 2958 // We haven't seen this declaration before. Give it a new ID and 2959 // enqueue it in the list of declarations to emit. 2960 ID = NextDeclID++; 2961 DeclTypesToEmit.push(const_cast<Decl *>(D)); 2962 } else if (ID < FirstDeclID && D->isChangedSinceDeserialization()) { 2963 // We don't add it to the replacement collection here, because we don't 2964 // have the offset yet. 2965 DeclTypesToEmit.push(const_cast<Decl *>(D)); 2966 // Reset the flag, so that we don't add this decl multiple times. 2967 const_cast<Decl *>(D)->setChangedSinceDeserialization(false); 2968 } 2969 2970 return ID; 2971} 2972 2973DeclID ASTWriter::getDeclID(const Decl *D) { 2974 if (D == 0) 2975 return 0; 2976 2977 assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!"); 2978 return DeclIDs[D]; 2979} 2980 2981void ASTWriter::AddDeclarationName(DeclarationName Name, RecordDataImpl &Record) { 2982 // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc. 2983 Record.push_back(Name.getNameKind()); 2984 switch (Name.getNameKind()) { 2985 case DeclarationName::Identifier: 2986 AddIdentifierRef(Name.getAsIdentifierInfo(), Record); 2987 break; 2988 2989 case DeclarationName::ObjCZeroArgSelector: 2990 case DeclarationName::ObjCOneArgSelector: 2991 case DeclarationName::ObjCMultiArgSelector: 2992 AddSelectorRef(Name.getObjCSelector(), Record); 2993 break; 2994 2995 case DeclarationName::CXXConstructorName: 2996 case DeclarationName::CXXDestructorName: 2997 case DeclarationName::CXXConversionFunctionName: 2998 AddTypeRef(Name.getCXXNameType(), Record); 2999 break; 3000 3001 case DeclarationName::CXXOperatorName: 3002 Record.push_back(Name.getCXXOverloadedOperator()); 3003 break; 3004 3005 case DeclarationName::CXXLiteralOperatorName: 3006 AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record); 3007 break; 3008 3009 case DeclarationName::CXXUsingDirective: 3010 // No extra data to emit 3011 break; 3012 } 3013} 3014 3015void ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, 3016 DeclarationName Name, RecordDataImpl &Record) { 3017 switch (Name.getNameKind()) { 3018 case DeclarationName::CXXConstructorName: 3019 case DeclarationName::CXXDestructorName: 3020 case DeclarationName::CXXConversionFunctionName: 3021 AddTypeSourceInfo(DNLoc.NamedType.TInfo, Record); 3022 break; 3023 3024 case DeclarationName::CXXOperatorName: 3025 AddSourceLocation( 3026 SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.BeginOpNameLoc), 3027 Record); 3028 AddSourceLocation( 3029 SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc), 3030 Record); 3031 break; 3032 3033 case DeclarationName::CXXLiteralOperatorName: 3034 AddSourceLocation( 3035 SourceLocation::getFromRawEncoding(DNLoc.CXXLiteralOperatorName.OpNameLoc), 3036 Record); 3037 break; 3038 3039 case DeclarationName::Identifier: 3040 case DeclarationName::ObjCZeroArgSelector: 3041 case DeclarationName::ObjCOneArgSelector: 3042 case DeclarationName::ObjCMultiArgSelector: 3043 case DeclarationName::CXXUsingDirective: 3044 break; 3045 } 3046} 3047 3048void ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo, 3049 RecordDataImpl &Record) { 3050 AddDeclarationName(NameInfo.getName(), Record); 3051 AddSourceLocation(NameInfo.getLoc(), Record); 3052 AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName(), Record); 3053} 3054 3055void ASTWriter::AddQualifierInfo(const QualifierInfo &Info, 3056 RecordDataImpl &Record) { 3057 AddNestedNameSpecifier(Info.NNS, Record); 3058 AddSourceRange(Info.NNSRange, Record); 3059 Record.push_back(Info.NumTemplParamLists); 3060 for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i) 3061 AddTemplateParameterList(Info.TemplParamLists[i], Record); 3062} 3063 3064void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, 3065 RecordDataImpl &Record) { 3066 // Nested name specifiers usually aren't too long. I think that 8 would 3067 // typically accomodate the vast majority. 3068 llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames; 3069 3070 // Push each of the NNS's onto a stack for serialization in reverse order. 3071 while (NNS) { 3072 NestedNames.push_back(NNS); 3073 NNS = NNS->getPrefix(); 3074 } 3075 3076 Record.push_back(NestedNames.size()); 3077 while(!NestedNames.empty()) { 3078 NNS = NestedNames.pop_back_val(); 3079 NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); 3080 Record.push_back(Kind); 3081 switch (Kind) { 3082 case NestedNameSpecifier::Identifier: 3083 AddIdentifierRef(NNS->getAsIdentifier(), Record); 3084 break; 3085 3086 case NestedNameSpecifier::Namespace: 3087 AddDeclRef(NNS->getAsNamespace(), Record); 3088 break; 3089 3090 case NestedNameSpecifier::TypeSpec: 3091 case NestedNameSpecifier::TypeSpecWithTemplate: 3092 AddTypeRef(QualType(NNS->getAsType(), 0), Record); 3093 Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); 3094 break; 3095 3096 case NestedNameSpecifier::Global: 3097 // Don't need to write an associated value. 3098 break; 3099 } 3100 } 3101} 3102 3103void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) { 3104 TemplateName::NameKind Kind = Name.getKind(); 3105 Record.push_back(Kind); 3106 switch (Kind) { 3107 case TemplateName::Template: 3108 AddDeclRef(Name.getAsTemplateDecl(), Record); 3109 break; 3110 3111 case TemplateName::OverloadedTemplate: { 3112 OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate(); 3113 Record.push_back(OvT->size()); 3114 for (OverloadedTemplateStorage::iterator I = OvT->begin(), E = OvT->end(); 3115 I != E; ++I) 3116 AddDeclRef(*I, Record); 3117 break; 3118 } 3119 3120 case TemplateName::QualifiedTemplate: { 3121 QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); 3122 AddNestedNameSpecifier(QualT->getQualifier(), Record); 3123 Record.push_back(QualT->hasTemplateKeyword()); 3124 AddDeclRef(QualT->getTemplateDecl(), Record); 3125 break; 3126 } 3127 3128 case TemplateName::DependentTemplate: { 3129 DependentTemplateName *DepT = Name.getAsDependentTemplateName(); 3130 AddNestedNameSpecifier(DepT->getQualifier(), Record); 3131 Record.push_back(DepT->isIdentifier()); 3132 if (DepT->isIdentifier()) 3133 AddIdentifierRef(DepT->getIdentifier(), Record); 3134 else 3135 Record.push_back(DepT->getOperator()); 3136 break; 3137 } 3138 } 3139} 3140 3141void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, 3142 RecordDataImpl &Record) { 3143 Record.push_back(Arg.getKind()); 3144 switch (Arg.getKind()) { 3145 case TemplateArgument::Null: 3146 break; 3147 case TemplateArgument::Type: 3148 AddTypeRef(Arg.getAsType(), Record); 3149 break; 3150 case TemplateArgument::Declaration: 3151 AddDeclRef(Arg.getAsDecl(), Record); 3152 break; 3153 case TemplateArgument::Integral: 3154 AddAPSInt(*Arg.getAsIntegral(), Record); 3155 AddTypeRef(Arg.getIntegralType(), Record); 3156 break; 3157 case TemplateArgument::Template: 3158 AddTemplateName(Arg.getAsTemplate(), Record); 3159 break; 3160 case TemplateArgument::Expression: 3161 AddStmt(Arg.getAsExpr()); 3162 break; 3163 case TemplateArgument::Pack: 3164 Record.push_back(Arg.pack_size()); 3165 for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end(); 3166 I != E; ++I) 3167 AddTemplateArgument(*I, Record); 3168 break; 3169 } 3170} 3171 3172void 3173ASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams, 3174 RecordDataImpl &Record) { 3175 assert(TemplateParams && "No TemplateParams!"); 3176 AddSourceLocation(TemplateParams->getTemplateLoc(), Record); 3177 AddSourceLocation(TemplateParams->getLAngleLoc(), Record); 3178 AddSourceLocation(TemplateParams->getRAngleLoc(), Record); 3179 Record.push_back(TemplateParams->size()); 3180 for (TemplateParameterList::const_iterator 3181 P = TemplateParams->begin(), PEnd = TemplateParams->end(); 3182 P != PEnd; ++P) 3183 AddDeclRef(*P, Record); 3184} 3185 3186/// \brief Emit a template argument list. 3187void 3188ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, 3189 RecordDataImpl &Record) { 3190 assert(TemplateArgs && "No TemplateArgs!"); 3191 Record.push_back(TemplateArgs->size()); 3192 for (int i=0, e = TemplateArgs->size(); i != e; ++i) 3193 AddTemplateArgument(TemplateArgs->get(i), Record); 3194} 3195 3196 3197void 3198ASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record) { 3199 Record.push_back(Set.size()); 3200 for (UnresolvedSetImpl::const_iterator 3201 I = Set.begin(), E = Set.end(); I != E; ++I) { 3202 AddDeclRef(I.getDecl(), Record); 3203 Record.push_back(I.getAccess()); 3204 } 3205} 3206 3207void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, 3208 RecordDataImpl &Record) { 3209 Record.push_back(Base.isVirtual()); 3210 Record.push_back(Base.isBaseOfClass()); 3211 Record.push_back(Base.getAccessSpecifierAsWritten()); 3212 AddTypeSourceInfo(Base.getTypeSourceInfo(), Record); 3213 AddSourceRange(Base.getSourceRange(), Record); 3214} 3215 3216void ASTWriter::FlushCXXBaseSpecifiers() { 3217 RecordData Record; 3218 for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) { 3219 Record.clear(); 3220 3221 // Record the offset of this base-specifier set. 3222 unsigned Index = CXXBaseSpecifiersToWrite[I].ID - FirstCXXBaseSpecifiersID; 3223 if (Index == CXXBaseSpecifiersOffsets.size()) 3224 CXXBaseSpecifiersOffsets.push_back(Stream.GetCurrentBitNo()); 3225 else { 3226 if (Index > CXXBaseSpecifiersOffsets.size()) 3227 CXXBaseSpecifiersOffsets.resize(Index + 1); 3228 CXXBaseSpecifiersOffsets[Index] = Stream.GetCurrentBitNo(); 3229 } 3230 3231 const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases, 3232 *BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd; 3233 Record.push_back(BEnd - B); 3234 for (; B != BEnd; ++B) 3235 AddCXXBaseSpecifier(*B, Record); 3236 Stream.EmitRecord(serialization::DECL_CXX_BASE_SPECIFIERS, Record); 3237 3238 // Flush any expressions that were written as part of the base specifiers. 3239 FlushStmts(); 3240 } 3241 3242 CXXBaseSpecifiersToWrite.clear(); 3243} 3244 3245void ASTWriter::AddCXXBaseOrMemberInitializers( 3246 const CXXBaseOrMemberInitializer * const *BaseOrMembers, 3247 unsigned NumBaseOrMembers, RecordDataImpl &Record) { 3248 Record.push_back(NumBaseOrMembers); 3249 for (unsigned i=0; i != NumBaseOrMembers; ++i) { 3250 const CXXBaseOrMemberInitializer *Init = BaseOrMembers[i]; 3251 3252 Record.push_back(Init->isBaseInitializer()); 3253 if (Init->isBaseInitializer()) { 3254 AddTypeSourceInfo(Init->getBaseClassInfo(), Record); 3255 Record.push_back(Init->isBaseVirtual()); 3256 } else { 3257 AddDeclRef(Init->getMember(), Record); 3258 } 3259 AddSourceLocation(Init->getMemberLocation(), Record); 3260 AddStmt(Init->getInit()); 3261 AddDeclRef(Init->getAnonUnionMember(), Record); 3262 AddSourceLocation(Init->getLParenLoc(), Record); 3263 AddSourceLocation(Init->getRParenLoc(), Record); 3264 Record.push_back(Init->isWritten()); 3265 if (Init->isWritten()) { 3266 Record.push_back(Init->getSourceOrder()); 3267 } else { 3268 Record.push_back(Init->getNumArrayIndices()); 3269 for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i) 3270 AddDeclRef(Init->getArrayIndex(i), Record); 3271 } 3272 } 3273} 3274 3275void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) { 3276 assert(D->DefinitionData); 3277 struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; 3278 Record.push_back(Data.UserDeclaredConstructor); 3279 Record.push_back(Data.UserDeclaredCopyConstructor); 3280 Record.push_back(Data.UserDeclaredCopyAssignment); 3281 Record.push_back(Data.UserDeclaredDestructor); 3282 Record.push_back(Data.Aggregate); 3283 Record.push_back(Data.PlainOldData); 3284 Record.push_back(Data.Empty); 3285 Record.push_back(Data.Polymorphic); 3286 Record.push_back(Data.Abstract); 3287 Record.push_back(Data.HasTrivialConstructor); 3288 Record.push_back(Data.HasTrivialCopyConstructor); 3289 Record.push_back(Data.HasTrivialCopyAssignment); 3290 Record.push_back(Data.HasTrivialDestructor); 3291 Record.push_back(Data.ComputedVisibleConversions); 3292 Record.push_back(Data.DeclaredDefaultConstructor); 3293 Record.push_back(Data.DeclaredCopyConstructor); 3294 Record.push_back(Data.DeclaredCopyAssignment); 3295 Record.push_back(Data.DeclaredDestructor); 3296 3297 Record.push_back(Data.NumBases); 3298 if (Data.NumBases > 0) 3299 AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases, 3300 Record); 3301 3302 // FIXME: Make VBases lazily computed when needed to avoid storing them. 3303 Record.push_back(Data.NumVBases); 3304 if (Data.NumVBases > 0) 3305 AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases, 3306 Record); 3307 3308 AddUnresolvedSet(Data.Conversions, Record); 3309 AddUnresolvedSet(Data.VisibleConversions, Record); 3310 // Data.Definition is the owning decl, no need to write it. 3311 AddDeclRef(Data.FirstFriend, Record); 3312} 3313 3314void ASTWriter::ReaderInitialized(ASTReader *Reader) { 3315 assert(Reader && "Cannot remove chain"); 3316 assert(!Chain && "Cannot replace chain"); 3317 assert(FirstDeclID == NextDeclID && 3318 FirstTypeID == NextTypeID && 3319 FirstIdentID == NextIdentID && 3320 FirstSelectorID == NextSelectorID && 3321 FirstMacroID == NextMacroID && 3322 FirstCXXBaseSpecifiersID == NextCXXBaseSpecifiersID && 3323 "Setting chain after writing has started."); 3324 Chain = Reader; 3325 3326 FirstDeclID += Chain->getTotalNumDecls(); 3327 FirstTypeID += Chain->getTotalNumTypes(); 3328 FirstIdentID += Chain->getTotalNumIdentifiers(); 3329 FirstSelectorID += Chain->getTotalNumSelectors(); 3330 FirstMacroID += Chain->getTotalNumMacroDefinitions(); 3331 FirstCXXBaseSpecifiersID += Chain->getTotalNumCXXBaseSpecifiers(); 3332 NextDeclID = FirstDeclID; 3333 NextTypeID = FirstTypeID; 3334 NextIdentID = FirstIdentID; 3335 NextSelectorID = FirstSelectorID; 3336 NextMacroID = FirstMacroID; 3337 NextCXXBaseSpecifiersID = FirstCXXBaseSpecifiersID; 3338} 3339 3340void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) { 3341 IdentifierIDs[II] = ID; 3342} 3343 3344void ASTWriter::TypeRead(TypeIdx Idx, QualType T) { 3345 // Always take the highest-numbered type index. This copes with an interesting 3346 // case for chained AST writing where we schedule writing the type and then, 3347 // later, deserialize the type from another AST. In this case, we want to 3348 // keep the higher-numbered entry so that we can properly write it out to 3349 // the AST file. 3350 TypeIdx &StoredIdx = TypeIdxs[T]; 3351 if (Idx.getIndex() >= StoredIdx.getIndex()) 3352 StoredIdx = Idx; 3353} 3354 3355void ASTWriter::DeclRead(DeclID ID, const Decl *D) { 3356 DeclIDs[D] = ID; 3357} 3358 3359void ASTWriter::SelectorRead(SelectorID ID, Selector S) { 3360 SelectorIDs[S] = ID; 3361} 3362 3363void ASTWriter::MacroDefinitionRead(serialization::MacroID ID, 3364 MacroDefinition *MD) { 3365 MacroDefinitions[MD] = ID; 3366} 3367 3368void ASTWriter::CompletedTagDefinition(const TagDecl *D) { 3369 assert(D->isDefinition()); 3370 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 3371 // We are interested when a PCH decl is modified. 3372 if (RD->getPCHLevel() > 0) { 3373 // A forward reference was mutated into a definition. Rewrite it. 3374 // FIXME: This happens during template instantiation, should we 3375 // have created a new definition decl instead ? 3376 RewriteDecl(RD); 3377 } 3378 3379 for (CXXRecordDecl::redecl_iterator 3380 I = RD->redecls_begin(), E = RD->redecls_end(); I != E; ++I) { 3381 CXXRecordDecl *Redecl = cast<CXXRecordDecl>(*I); 3382 if (Redecl == RD) 3383 continue; 3384 3385 // We are interested when a PCH decl is modified. 3386 if (Redecl->getPCHLevel() > 0) { 3387 UpdateRecord &Record = DeclUpdates[Redecl]; 3388 Record.push_back(UPD_CXX_SET_DEFINITIONDATA); 3389 assert(Redecl->DefinitionData); 3390 assert(Redecl->DefinitionData->Definition == D); 3391 AddDeclRef(D, Record); // the DefinitionDecl 3392 } 3393 } 3394 } 3395} 3396void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { 3397 // TU and namespaces are handled elsewhere. 3398 if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC)) 3399 return; 3400 3401 if (!(D->getPCHLevel() == 0 && cast<Decl>(DC)->getPCHLevel() > 0)) 3402 return; // Not a source decl added to a DeclContext from PCH. 3403 3404 AddUpdatedDeclContext(DC); 3405} 3406 3407void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { 3408 assert(D->isImplicit()); 3409 if (!(D->getPCHLevel() == 0 && RD->getPCHLevel() > 0)) 3410 return; // Not a source member added to a class from PCH. 3411 if (!isa<CXXMethodDecl>(D)) 3412 return; // We are interested in lazily declared implicit methods. 3413 3414 // A decl coming from PCH was modified. 3415 assert(RD->isDefinition()); 3416 UpdateRecord &Record = DeclUpdates[RD]; 3417 Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER); 3418 AddDeclRef(D, Record); 3419} 3420 3421void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, 3422 const ClassTemplateSpecializationDecl *D) { 3423 // The specializations set is kept in the canonical template. 3424 TD = TD->getCanonicalDecl(); 3425 if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0)) 3426 return; // Not a source specialization added to a template from PCH. 3427 3428 UpdateRecord &Record = DeclUpdates[TD]; 3429 Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); 3430 AddDeclRef(D, Record); 3431} 3432 3433ASTSerializationListener::~ASTSerializationListener() { } 3434