ASTWriter.cpp revision bef1a7b9c175d37e4a727e6ce68bd05232fa6970
14ee2ad04344446e610172a0e73949212923014dfSebastian Redl//===--- ASTWriter.cpp - AST File Writer ----------------------------------===// 22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// The LLVM Compiler Infrastructure 42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// This file is distributed under the University of Illinois Open Source 62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// License. See LICENSE.TXT for details. 72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===// 92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 10a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl// This file defines the ASTWriter class, which writes AST files. 112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===// 132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 147faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl#include "clang/Serialization/ASTWriter.h" 150eca89e9890db4d8336ce762a5b359a1d58ca02bArgyrios Kyrtzidis#include "ASTCommon.h" 16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Sema.h" 17e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/IdentifierResolver.h" 182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/ASTContext.h" 192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/Decl.h" 202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/DeclContextInternals.h" 212a7fb27913999d132cf9e10e03dc5271faa2e9d3John McCall#include "clang/AST/DeclTemplate.h" 2289eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis#include "clang/AST/DeclFriend.h" 230b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor#include "clang/AST/Expr.h" 247a1fad38256eb4c5129359be85ba1ea1678eb5c9John McCall#include "clang/AST/ExprCXX.h" 252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/Type.h" 26a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall#include "clang/AST/TypeLocVisitor.h" 276ab7cd853e9c15cf986a8a7c3db1f8d20e275409Sebastian Redl#include "clang/Serialization/ASTReader.h" 287c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner#include "clang/Lex/MacroInfo.h" 296a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor#include "clang/Lex/PreprocessingRecord.h" 307c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner#include "clang/Lex/Preprocessor.h" 3183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff#include "clang/Lex/HeaderSearch.h" 3214f79002e58556798e86168c63e48d533287eda5Douglas Gregor#include "clang/Basic/FileManager.h" 3310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#include "clang/Basic/OnDiskHashTable.h" 343251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor#include "clang/Basic/SourceManager.h" 3514f79002e58556798e86168c63e48d533287eda5Douglas Gregor#include "clang/Basic/SourceManagerInternals.h" 36bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor#include "clang/Basic/TargetInfo.h" 372bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor#include "clang/Basic/Version.h" 38ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor#include "llvm/ADT/APFloat.h" 390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#include "llvm/ADT/APInt.h" 4017fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor#include "llvm/ADT/StringExtras.h" 4117fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor#include "llvm/Bitcode/BitstreamWriter.h" 422596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar#include "llvm/Support/MemoryBuffer.h" 432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/System/Path.h" 44fbfd180495e7800975c6d9bdc6d24e706ef70e34Michael J. Spencer#include <cstdio> 4514f79002e58556798e86168c63e48d533287eda5Douglas Gregorusing namespace clang; 4603013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencerusing namespace clang::serialization; 47f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 483c304bd9ec2b4611572d4cbae9e1727bbecb5dc9Chris Lattnertemplate <typename T, typename Allocator> 49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas GregorT *data(std::vector<T, Allocator> &v) { 50f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return v.empty() ? 0 : &v.front(); 512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 528538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redltemplate <typename T, typename Allocator> 532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorconst T *data(const std::vector<T, Allocator> &v) { 54ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl return v.empty() ? 0 : &v.front(); 555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner} 565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner 575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner//===----------------------------------------------------------------------===// 586e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer// Type serialization 59ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl//===----------------------------------------------------------------------===// 606e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer 616e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramernamespace { 625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner class ASTTypeWriter { 635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner ASTWriter &Writer; 646e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer ASTWriter::RecordDataImpl &Record; 65ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl 66ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl public: 672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor /// \brief Type code that corresponds to the record generated. 682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor TypeCode Code; 692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 7012b1c7615d4f9a2edc544be499f895f16ac100edChris Lattner ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) 712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { } 723397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 73a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl void VisitArrayType(const ArrayType *T); 7489eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis void VisitFunctionType(const FunctionType *T); 752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor void VisitTagType(const TagType *T); 762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T); 788538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl#define ABSTRACT_TYPE(Class, Base) 792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/TypeNodes.def" 8089eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis }; 818538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) { 842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor assert(false && "Built-in types are never serialized"); 852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitComplexType(const ComplexType *T) { 882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTypeRef(T->getElementType(), Record); 892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_COMPLEX; 902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitPointerType(const PointerType *T) { 933397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Writer.AddTypeRef(T->getPointeeType(), Record); 94b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie Code = TYPE_POINTER; 952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 973397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { 982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTypeRef(T->getPointeeType(), Record); 998538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_BLOCK_POINTER; 1002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1023397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) { 1032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTypeRef(T->getPointeeType(), Record); 1048538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_LVALUE_REFERENCE; 1052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1073397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) { 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Writer.AddTypeRef(T->getPointeeType(), Record); 1098538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_RVALUE_REFERENCE; 1102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1123397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) { 113df1550fc59b51681d37225934fe4e3acac321621Richard Smith Writer.AddTypeRef(T->getPointeeType(), Record); 114df1550fc59b51681d37225934fe4e3acac321621Richard Smith Writer.AddTypeRef(QualType(T->getClass(), 0), Record); 1158538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_MEMBER_POINTER; 1162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1183397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitArrayType(const ArrayType *T) { 119df1550fc59b51681d37225934fe4e3acac321621Richard Smith Writer.AddTypeRef(T->getElementType(), Record); 1208538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.push_back(T->getSizeModifier()); // FIXME: stable values 1212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values 1222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1233397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) { 1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump VisitArrayType(T); 1268538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Writer.AddAPInt(T->getSize(), Record); 1272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_CONSTANT_ARRAY; 1282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1293397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 1302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) { 1312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor VisitArrayType(T); 1320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Code = TYPE_INCOMPLETE_ARRAY; 1332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1353397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { 1362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor VisitArrayType(T); 1372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddSourceLocation(T->getLBracketLoc(), Record); 1388538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Writer.AddSourceLocation(T->getRBracketLoc(), Record); 1392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddStmt(T->getSizeExpr()); 1402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_VARIABLE_ARRAY; 1413397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl} 1422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1438538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid ASTTypeWriter::VisitVectorType(const VectorType *T) { 1442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTypeRef(T->getElementType(), Record); 1452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record.push_back(T->getNumElements()); 1463397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Record.push_back(T->getAltiVecSpecific()); 1472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_VECTOR; 1487e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor} 1497e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor 150c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregorvoid ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) { 1518538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl VisitVectorType(T); 1522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_EXT_VECTOR; 1532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1543397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 1552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitFunctionType(const FunctionType *T) { 1562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTypeRef(T->getResultType(), Record); 157e86d78cf4754a6aef2cf9a33d847aa15338e276fBob Wilson FunctionType::ExtInfo C = T->getExtInfo(); 1588538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.push_back(C.getNoReturn()); 1592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record.push_back(C.getRegParm()); 1602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // FIXME: need to stabilize encoding of calling convention... 1613397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Record.push_back(C.getCC()); 1622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1638538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 1642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { 1652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor VisitFunctionType(T); 1663397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Code = TYPE_FUNCTION_NO_PROTO; 1672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 168264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola 169264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindolavoid ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { 170a49218e17bcbb1acde0245773173e2c0c42f4f19Eli Friedman VisitFunctionType(T); 171425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola Record.push_back(T->getNumArgs()); 172ab8bbf4ebd3e3e6eab913cb044772a62b7581941Douglas Gregor for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I) 173264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola Writer.AddTypeRef(T->getArgType(I), Record); 174f85e193739c953358c865005855253af4f68a497John McCall Record.push_back(T->isVariadic()); 1752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record.push_back(T->getTypeQuals()); 1762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record.push_back(T->hasExceptionSpec()); 1773397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Record.push_back(T->hasAnyExceptionSpec()); 1782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record.push_back(T->getNumExceptions()); 1798538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) 1802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTypeRef(T->getExceptionType(I), Record); 1812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_FUNCTION_PROTO; 1823397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl} 1832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 1852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddDeclRef(T->getDecl(), Record); 1862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_UNRESOLVED_USING; 1872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 189c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregorvoid ASTTypeWriter::VisitTypedefType(const TypedefType *T) { 19060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Writer.AddDeclRef(T->getDecl(), Record); 19160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl assert(!T->isCanonicalUnqualified() && "Invalid typedef ?"); 19260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record); 19360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Code = TYPE_TYPEDEF; 19460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl} 19560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 19660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redlvoid ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) { 19760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Writer.AddStmt(T->getUnderlyingExpr()); 1988538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_TYPEOF_EXPR; 1992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 2002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2013397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) { 202ed97649e9574b9d854fa4d6109c9333ae0993554John McCall Writer.AddTypeRef(T->getUnderlyingType(), Record); 2038538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_TYPEOF; 204ed97649e9574b9d854fa4d6109c9333ae0993554John McCall} 205ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 2063397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { 2072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddStmt(T->getUnderlyingExpr()); 2089763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis Code = TYPE_DECLTYPE; 2099763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis} 2108538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 2112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTTypeWriter::VisitTagType(const TagType *T) { 2122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record.push_back(T->isDependentType()); 2133397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Writer.AddDeclRef(T->getDecl(), Record); 214c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor assert(!T->isBeingDefined() && 2158538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl "Cannot serialize in the middle of a type definition"); 2162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 2172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2183397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitRecordType(const RecordType *T) { 2192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor VisitTagType(T); 2208538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_RECORD; 2212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 2222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2233397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitEnumType(const EnumType *T) { 224395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson VisitTagType(T); 2258538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Code = TYPE_ENUM; 226395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson} 227395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson 228ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntvoid 229ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean HuntASTTypeWriter::VisitSubstTemplateTypeParmType( 230ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt const SubstTemplateTypeParmType *T) { 231ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record); 232ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt Writer.AddTypeRef(T->getReplacementType(), Record); 233ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt Code = TYPE_SUBST_TEMPLATE_TYPE_PARM; 234ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt} 23534b41d939a1328f484511c6002ba2456db879a29Richard Smith 23634b41d939a1328f484511c6002ba2456db879a29Richard Smithvoid 23734b41d939a1328f484511c6002ba2456db879a29Richard SmithASTTypeWriter::VisitTemplateSpecializationType( 23834b41d939a1328f484511c6002ba2456db879a29Richard Smith const TemplateSpecializationType *T) { 23934b41d939a1328f484511c6002ba2456db879a29Richard Smith Record.push_back(T->isDependentType()); 2403397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Writer.AddTemplateName(T->getTemplateName(), Record); 241be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis Record.push_back(T->getNumArgs()); 2422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end(); 2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ArgI != ArgE; ++ArgI) 2442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTemplateArgument(*ArgI, Record); 2452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType() 2462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor : T->getCanonicalTypeInternal(), 2473397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Record); 2482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_TEMPLATE_SPECIALIZATION; 2498538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 2502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid 2523397c5570369f19b2d6c52e898f708d75ceede1fSebastian RedlASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 2532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor VisitArrayType(T); 2548538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Writer.AddStmt(T->getSizeExpr()); 2552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddSourceRange(T->getBracketsRange(), Record); 2562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Code = TYPE_DEPENDENT_SIZED_ARRAY; 2579d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall} 2589d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall 2599d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCallvoid 2609d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCallASTTypeWriter::VisitDependentSizedExtVectorType( 2619d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall const DependentSizedExtVectorType *T) { 2629d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall // FIXME: Serialize this type (C++ only) 2639d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall assert(false && "Cannot serialize dependent sized extended vector types"); 2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 2653397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 26649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCallvoid 26749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCallASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 26849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall Record.push_back(T->getDepth()); 2698538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.push_back(T->getIndex()); 27049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall Record.push_back(T->isParameterPack()); 27149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall Writer.AddIdentifierRef(T->getName(), Record); 27249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall Code = TYPE_TEMPLATE_TYPE_PARM; 273c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor} 274c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor 275c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregorvoid 276c3069d618f4661d923cb1b5c4525b082fce73b04Douglas GregorASTTypeWriter::VisitDependentNameType(const DependentNameType *T) { 277c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor Record.push_back(T->getKeyword()); 278c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 279c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor Writer.AddIdentifierRef(T->getIdentifier(), Record); 280c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType() 2813397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl : T->getCanonicalTypeInternal(), 2822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Record); 283be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis Code = TYPE_DEPENDENT_NAME; 28490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis} 28590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis 28690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidisvoid 28790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios KyrtzidisASTTypeWriter::VisitDependentTemplateSpecializationType( 28890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis const DependentTemplateSpecializationType *T) { 2893e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Record.push_back(T->getKeyword()); 2903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 2919763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis Writer.AddIdentifierRef(T->getIdentifier(), Record); 2929763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis Record.push_back(T->getNumArgs()); 2938538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl for (DependentTemplateSpecializationType::iterator 29490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis I = T->begin(), E = T->end(); I != E; ++I) 29590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Writer.AddTemplateArgument(*I, Record); 29690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION; 2973397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl} 298ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis 299ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidisvoid ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { 300ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis Record.push_back(T->getKeyword()); 3018538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 30290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Writer.AddTypeRef(T->getNamedType(), Record); 30390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Code = TYPE_ELABORATED; 30490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis} 3053397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 30690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidisvoid ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) { 30790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Writer.AddDeclRef(T->getDecl(), Record); 308b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie Writer.AddTypeRef(T->getInjectedSpecializationType(), Record); 30990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Code = TYPE_INJECTED_CLASS_NAME; 31090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis} 31190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis 3123397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 31390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Writer.AddDeclRef(T->getDecl(), Record); 31490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Code = TYPE_OBJC_INTERFACE; 31590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis} 3164fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth 3178538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) { 31890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Writer.AddTypeRef(T->getBaseType(), Record); 31990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Record.push_back(T->getNumProtocols()); 32090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis for (ObjCObjectType::qual_iterator I = T->qual_begin(), 3213397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl E = T->qual_end(); I != E; ++I) 3228dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis Writer.AddDeclRef(*I, Record); 3238dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis Code = TYPE_OBJC_OBJECT; 3248dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis} 325f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis 326f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidisvoid 327f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios KyrtzidisASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 3288538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Writer.AddTypeRef(T->getPointeeType(), Record); 32990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis Code = TYPE_OBJC_OBJECT_POINTER; 33090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis} 33190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis 3323397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlnamespace { 33390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis 3343acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidisclass TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { 3353acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis ASTWriter &Writer; 3363acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis ASTWriter::RecordDataImpl &Record; 3373acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis 3383acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidispublic: 3393acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) 3403acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis : Writer(Writer), Record(Record) { } 3418538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 3422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define ABSTRACT_TYPELOC(CLASS, PARENT) 3432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define TYPELOC(CLASS, PARENT) \ 3447536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 3457536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor#include "clang/AST/TypeLocNodes.def" 346cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor 347cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor void VisitArrayTypeLoc(ArrayTypeLoc TyLoc); 348cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc); 349cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor}; 3507536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor 3517536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor} 3527536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor 353075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnaravoid TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 354075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara // nothing to do 355075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara} 356075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnaravoid TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 357075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara Writer.AddSourceLocation(TL.getBuiltinLoc(), Record); 3583397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl if (TL.needsExtraLocalData()) { 359465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara Record.push_back(TL.getWrittenTypeSpec()); 3603acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis Record.push_back(TL.getWrittenSignSpec()); 3613acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis Record.push_back(TL.getWrittenWidthSpec()); 3628538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.push_back(TL.hasModeAttr()); 3632cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 3642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 3653397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { 3663cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 36731f17ecbef57b5679c017c375db330546b7b5145John McCall} 3688538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { 3693cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall Writer.AddSourceLocation(TL.getStarLoc(), Record); 3703cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall} 3713397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 372deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor Writer.AddSourceLocation(TL.getCaretLoc(), Record); 3738538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 374c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallvoid TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 375c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall Writer.AddSourceLocation(TL.getAmpLoc(), Record); 3763397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl} 377c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallvoid TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 3782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record); 379c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall} 380446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroffvoid TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 381446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff Writer.AddSourceLocation(TL.getStarLoc(), Record); 3828538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 3832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { 3842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Writer.AddSourceLocation(TL.getLBracketLoc(), Record); 385d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff Writer.AddSourceLocation(TL.getRBracketLoc(), Record); 3863397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Record.push_back(TL.getSizeExpr() ? 1 : 0); 3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (TL.getSizeExpr()) 3888538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Writer.AddStmt(TL.getSizeExpr()); 3892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 3902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { 391b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman VisitArrayTypeLoc(TL); 392b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman} 393b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedmanvoid TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { 394b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman VisitArrayTypeLoc(TL); 395b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman} 396b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedmanvoid TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { 397a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall VisitArrayTypeLoc(TL); 398a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall} 399a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCallvoid TypeLocWriter::VisitDependentSizedArrayTypeLoc( 400a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl DependentSizedArrayTypeLoc TL) { 40189eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis VisitArrayTypeLoc(TL); 402a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall} 403a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCallvoid TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( 40489eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis DependentSizedExtVectorTypeLoc TL) { 405a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 406a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall} 40751bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { 408a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 40951bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 410a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCallvoid TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { 411a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 41251bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 41351bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { 414a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall Writer.AddSourceLocation(TL.getLParenLoc(), Record); 415a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall Writer.AddSourceLocation(TL.getRParenLoc(), Record); 416a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall Record.push_back(TL.getTrailingReturn()); 417a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 41851bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddDeclRef(TL.getArg(i), Record); 41951bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 42051bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { 42151bd803fbdade51d674598ed45da3d54190a656cJohn McCall VisitFunctionTypeLoc(TL); 422ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor} 423ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregorvoid TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { 424ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor VisitFunctionTypeLoc(TL); 425ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor} 426ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregorvoid TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 427ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor Writer.AddSourceLocation(TL.getNameLoc(), Record); 428ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor} 42951bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 43051bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 43151bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 43251bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 43351bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 43451bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getLParenLoc(), Record); 43551bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getRParenLoc(), Record); 43651bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 43751bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 43851bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 43951bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getLParenLoc(), Record); 44051bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getRParenLoc(), Record); 44151bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record); 44251bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 44351bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 44451bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 44551bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 44651bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { 447b6ab6c1ca733fda2302a1c5066bdfc6218c89e41Abramo Bagnara Writer.AddSourceLocation(TL.getNameLoc(), Record); 44851bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 44951bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { 45051bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 45151bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 45251bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 45351bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 45451bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 45551bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( 45651bd803fbdade51d674598ed45da3d54190a656cJohn McCall SubstTemplateTypeParmTypeLoc TL) { 45751bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 45851bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 45951bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitTemplateSpecializationTypeLoc( 46051bd803fbdade51d674598ed45da3d54190a656cJohn McCall TemplateSpecializationTypeLoc TL) { 46151bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record); 46251bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 46351bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 46451bd803fbdade51d674598ed45da3d54190a656cJohn McCall for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 46551bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(), 46651bd803fbdade51d674598ed45da3d54190a656cJohn McCall TL.getArgLoc(i).getLocInfo(), Record); 46751bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 46851bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { 46951bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 47051bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceRange(TL.getQualifierRange(), Record); 47151bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 47251bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 47351bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 47451bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 47551bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { 47651bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 47751bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceRange(TL.getQualifierRange(), Record); 47851bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 47951bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 480796aa443ab5ed036f42ef33fed629e1b4b34871bAbramo Bagnaravoid TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( 481796aa443ab5ed036f42ef33fed629e1b4b34871bAbramo Bagnara DependentTemplateSpecializationTypeLoc TL) { 482dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 48351bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceRange(TL.getQualifierRange(), Record); 48451bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 48551bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 48651bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 48751bd803fbdade51d674598ed45da3d54190a656cJohn McCall for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) 48851bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(), 48951bd803fbdade51d674598ed45da3d54190a656cJohn McCall TL.getArgLoc(I).getLocInfo(), Record); 49051bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 49151bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 492ed97649e9574b9d854fa4d6109c9333ae0993554John McCall Writer.AddSourceLocation(TL.getNameLoc(), Record); 493ed97649e9574b9d854fa4d6109c9333ae0993554John McCall} 494ed97649e9574b9d854fa4d6109c9333ae0993554John McCallvoid TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 49551bd803fbdade51d674598ed45da3d54190a656cJohn McCall Record.push_back(TL.hasBaseTypeAsWritten()); 49651bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 49751bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 49851bd803fbdade51d674598ed45da3d54190a656cJohn McCall for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) 499cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); 500cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall} 501cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCallvoid TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 50251bd803fbdade51d674598ed45da3d54190a656cJohn McCall Writer.AddSourceLocation(TL.getStarLoc(), Record); 50351bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 504cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall 505cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall//===----------------------------------------------------------------------===// 506cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall// ASTWriter Implementation 507cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall//===----------------------------------------------------------------------===// 50851bd803fbdade51d674598ed45da3d54190a656cJohn McCall 50951bd803fbdade51d674598ed45da3d54190a656cJohn McCallstatic void EmitBlockID(unsigned ID, const char *Name, 51051bd803fbdade51d674598ed45da3d54190a656cJohn McCall llvm::BitstreamWriter &Stream, 511a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall ASTWriter::RecordDataImpl &Record) { 512ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt Record.clear(); 513ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt Record.push_back(ID); 514ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); 515ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt 516ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt // Emit the block name if present. 517ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt if (Name == 0 || Name[0] == 0) return; 51834b41d939a1328f484511c6002ba2456db879a29Richard Smith Record.clear(); 51934b41d939a1328f484511c6002ba2456db879a29Richard Smith while (*Name) 52034b41d939a1328f484511c6002ba2456db879a29Richard Smith Record.push_back(*Name++); 52151bd803fbdade51d674598ed45da3d54190a656cJohn McCall Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record); 52251bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 523a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall 52451bd803fbdade51d674598ed45da3d54190a656cJohn McCallstatic void EmitRecordID(unsigned ID, const char *Name, 52551bd803fbdade51d674598ed45da3d54190a656cJohn McCall llvm::BitstreamWriter &Stream, 526a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall ASTWriter::RecordDataImpl &Record) { 5279d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall Record.clear(); 5289d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall Record.push_back(ID); 5299d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall while (*Name) 5309d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall Record.push_back(*Name++); 5319d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record); 5329d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall} 5339d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall 5349d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCallstatic void AddStmtsExprs(llvm::BitstreamWriter &Stream, 5359d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall ASTWriter::RecordDataImpl &Record) { 5369d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 5379d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall RECORD(STMT_STOP); 5389d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall RECORD(STMT_NULL_PTR); 5399d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall RECORD(STMT_NULL); 5409d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall RECORD(STMT_COMPOUND); 5419d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall RECORD(STMT_CASE); 54251bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(STMT_DEFAULT); 54351bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(STMT_LABEL); 544a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall RECORD(STMT_IF); 54549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall RECORD(STMT_SWITCH); 54649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall RECORD(STMT_WHILE); 54749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall RECORD(STMT_DO); 54849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall RECORD(STMT_FOR); 549c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor RECORD(STMT_GOTO); 550c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor RECORD(STMT_INDIRECT_GOTO); 551c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor RECORD(STMT_CONTINUE); 552c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor RECORD(STMT_BREAK); 55351bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(STMT_RETURN); 55451bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(STMT_DECL); 555833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall RECORD(STMT_ASM); 556833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall RECORD(EXPR_PREDEFINED); 557833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall RECORD(EXPR_DECL_REF); 558833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall RECORD(EXPR_INTEGER_LITERAL); 55944f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis RECORD(EXPR_FLOATING_LITERAL); 56044f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis RECORD(EXPR_IMAGINARY_LITERAL); 561a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall RECORD(EXPR_STRING_LITERAL); 562075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara RECORD(EXPR_CHARACTER_LITERAL); 563075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara RECORD(EXPR_PAREN); 564075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara RECORD(EXPR_UNARY_OPERATOR); 565075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara RECORD(EXPR_SIZEOF_ALIGN_OF); 566465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara RECORD(EXPR_ARRAY_SUBSCRIPT); 567e4da7a034a2fcf4b14d0bcc28d05de0878159061Abramo Bagnara RECORD(EXPR_CALL); 5689e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor RECORD(EXPR_MEMBER); 569a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall RECORD(EXPR_BINARY_OPERATOR); 5703cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR); 5713cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall RECORD(EXPR_CONDITIONAL_OPERATOR); 5723cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall RECORD(EXPR_IMPLICIT_CAST); 5734714c12a1ab759156b78be8f109ea4c12213af57Douglas Gregor RECORD(EXPR_CSTYLE_CAST); 574e4da7a034a2fcf4b14d0bcc28d05de0878159061Abramo Bagnara RECORD(EXPR_COMPOUND_LITERAL); 5752494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor RECORD(EXPR_EXT_VECTOR_ELEMENT); 57651bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(EXPR_INIT_LIST); 577a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall RECORD(EXPR_DESIGNATED_INIT); 57833500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_IMPLICIT_VALUE_INIT); 57933500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_VA_ARG); 58033500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_ADDR_LABEL); 58194fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor RECORD(EXPR_STMT); 58233500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_TYPES_COMPATIBLE); 58333500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_CHOOSE); 58433500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_GNU_NULL); 58533500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_SHUFFLE_VECTOR); 58644f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis RECORD(EXPR_BLOCK); 58744f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis RECORD(EXPR_BLOCK_DECL_REF); 58833500955d731c73717af52088b7fc0e7a85681e7John McCall RECORD(EXPR_OBJC_STRING_LITERAL); 5897536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor RECORD(EXPR_OBJC_ENCODE); 5907536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor RECORD(EXPR_OBJC_SELECTOR_EXPR); 5917536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor RECORD(EXPR_OBJC_PROTOCOL_EXPR); 59251bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(EXPR_OBJC_IVAR_REF_EXPR); 59351bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(EXPR_OBJC_PROPERTY_REF_EXPR); 594c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall RECORD(EXPR_OBJC_KVC_REF_EXPR); 595c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall RECORD(EXPR_OBJC_MESSAGE_EXPR); 596c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall RECORD(STMT_OBJC_FOR_COLLECTION); 59754e14c4db764c0636160d26c5bbf491637c83a76John McCall RECORD(STMT_OBJC_CATCH); 59854e14c4db764c0636160d26c5bbf491637c83a76John McCall RECORD(STMT_OBJC_FINALLY); 59954e14c4db764c0636160d26c5bbf491637c83a76John McCall RECORD(STMT_OBJC_AT_TRY); 60054e14c4db764c0636160d26c5bbf491637c83a76John McCall RECORD(STMT_OBJC_AT_SYNCHRONIZED); 601a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall RECORD(STMT_OBJC_AT_THROW); 60251bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(EXPR_CXX_OPERATOR_CALL); 60351bd803fbdade51d674598ed45da3d54190a656cJohn McCall RECORD(EXPR_CXX_CONSTRUCT); 604a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall RECORD(EXPR_CXX_STATIC_CAST); 605b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman RECORD(EXPR_CXX_DYNAMIC_CAST); 606b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman RECORD(EXPR_CXX_REINTERPRET_CAST); 607b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman RECORD(EXPR_CXX_CONST_CAST); 608b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman RECORD(EXPR_CXX_FUNCTIONAL_CAST); 609b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman RECORD(EXPR_CXX_BOOL_LITERAL); 610a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall RECORD(EXPR_CXX_NULL_PTR_LITERAL); 6114dcf151a555ff51e4d643e8e6eeb80f121d11d1bChris Lattner#undef RECORD 612a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl} 6132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 6142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTWriter::WriteBlockInfoBlock() { 615b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RecordData Record; 616b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3); 61789eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis 618b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record) 619b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 620b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 621b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner // AST Top-Level Block. 622b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner BLOCK(AST_BLOCK); 623b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(ORIGINAL_FILE_NAME); 624b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(TYPE_OFFSET); 625b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(DECL_OFFSET); 626b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(LANGUAGE_OPTIONS); 627b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(METADATA); 628b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(IDENTIFIER_OFFSET); 629b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(IDENTIFIER_TABLE); 630b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(EXTERNAL_DEFINITIONS); 631b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(SPECIAL_TYPES); 63289eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis RECORD(STATISTICS); 633b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(TENTATIVE_DEFINITIONS); 634b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(UNUSED_FILESCOPED_DECLS); 635b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS); 636b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(SELECTOR_OFFSETS); 637b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RECORD(METHOD_POOL); 6380558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(PP_COUNTER_VALUE); 6390558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(SOURCE_LOCATION_OFFSETS); 6400558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(SOURCE_LOCATION_PRELOADS); 64189eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis RECORD(STAT_CACHE); 6428538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl RECORD(EXT_VECTOR_DECLS); 6430558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(VERSION_CONTROL_BRANCH_REVISION); 6440558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(MACRO_DEFINITION_OFFSETS); 6450558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(CHAINED_METADATA); 6460558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(REFERENCED_SELECTOR_POOL); 6470558df2da807646e65d4fa290f4e92114af1a746Chris Lattner 6480558df2da807646e65d4fa290f4e92114af1a746Chris Lattner // SourceManager Block. 6490558df2da807646e65d4fa290f4e92114af1a746Chris Lattner BLOCK(SOURCE_MANAGER_BLOCK); 6500558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(SM_SLOC_FILE_ENTRY); 6510558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(SM_SLOC_BUFFER_ENTRY); 6520558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(SM_SLOC_BUFFER_BLOB); 6530558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(SM_SLOC_INSTANTIATION_ENTRY); 6540558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(SM_LINE_TABLE); 6550558df2da807646e65d4fa290f4e92114af1a746Chris Lattner 6560558df2da807646e65d4fa290f4e92114af1a746Chris Lattner // Preprocessor Block. 6570558df2da807646e65d4fa290f4e92114af1a746Chris Lattner BLOCK(PREPROCESSOR_BLOCK); 6580558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(PP_MACRO_OBJECT_LIKE); 6590558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(PP_MACRO_FUNCTION_LIKE); 6600558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(PP_TOKEN); 6610558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(PP_MACRO_INSTANTIATION); 6620558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(PP_MACRO_DEFINITION); 6630558df2da807646e65d4fa290f4e92114af1a746Chris Lattner 6640558df2da807646e65d4fa290f4e92114af1a746Chris Lattner // Decls and Types block. 6650558df2da807646e65d4fa290f4e92114af1a746Chris Lattner BLOCK(DECLTYPES_BLOCK); 6660558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_EXT_QUAL); 6670558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_COMPLEX); 6680558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_POINTER); 6690558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_BLOCK_POINTER); 6700558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_LVALUE_REFERENCE); 6710558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_RVALUE_REFERENCE); 6720558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_MEMBER_POINTER); 6730558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_CONSTANT_ARRAY); 6740558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_INCOMPLETE_ARRAY); 6750558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_VARIABLE_ARRAY); 6760558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_VECTOR); 6770558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_EXT_VECTOR); 6780558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_FUNCTION_PROTO); 6790558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_FUNCTION_NO_PROTO); 6800558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_TYPEDEF); 6810558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_TYPEOF_EXPR); 6820558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_TYPEOF); 6830558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_RECORD); 6840558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_ENUM); 6850558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_OBJC_INTERFACE); 6860558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_OBJC_OBJECT); 6870558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(TYPE_OBJC_OBJECT_POINTER); 6880558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_TRANSLATION_UNIT); 6890558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_TYPEDEF); 6900558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_ENUM); 6910558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_RECORD); 6920558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_ENUM_CONSTANT); 693f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne RECORD(DECL_FUNCTION); 6940558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_METHOD); 6950558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_INTERFACE); 6960558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_PROTOCOL); 6970558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_IVAR); 6980558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_AT_DEFS_FIELD); 6990558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_CLASS); 7000558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_FORWARD_PROTOCOL); 7010558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_CATEGORY); 7020558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_CATEGORY_IMPL); 7030558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_IMPLEMENTATION); 7040558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_COMPATIBLE_ALIAS); 7050558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_PROPERTY); 7060558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_OBJC_PROPERTY_IMPL); 7070558df2da807646e65d4fa290f4e92114af1a746Chris Lattner RECORD(DECL_FIELD); 708eb7f96141f754150a92433286fa385910a22f494Sam Weinig RECORD(DECL_VAR); 709eb7f96141f754150a92433286fa385910a22f494Sam Weinig RECORD(DECL_IMPLICIT_PARAM); 710eb7f96141f754150a92433286fa385910a22f494Sam Weinig RECORD(DECL_PARM_VAR); 711eb7f96141f754150a92433286fa385910a22f494Sam Weinig RECORD(DECL_FILE_SCOPE_ASM); 712eb7f96141f754150a92433286fa385910a22f494Sam Weinig RECORD(DECL_BLOCK); 713eb7f96141f754150a92433286fa385910a22f494Sam Weinig RECORD(DECL_CONTEXT_LEXICAL); 714eb7f96141f754150a92433286fa385910a22f494Sam Weinig RECORD(DECL_CONTEXT_VISIBLE); 715eb7f96141f754150a92433286fa385910a22f494Sam Weinig // Statements and Exprs can occur in the Decls and Types block. 716eb7f96141f754150a92433286fa385910a22f494Sam Weinig AddStmtsExprs(Stream, Record); 717b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor#undef RECORD 718b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor#undef BLOCK 719b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Stream.ExitBlock(); 720b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor} 721b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 722b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// \brief Adjusts the given filename to only write out the portion of the 723b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// filename that is not part of the system root directory. 724b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// 725b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// \param Filename the file name to adjust. 726b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// 727b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and 728b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// the returned filename will be adjusted by this system root. 729b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// 730b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// \returns either the original filename (if it needs no adjustment) or the 731b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor/// adjusted filename (which points into the @p Filename parameter). 732b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregorstatic const char * 733b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas GregoradjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) { 734b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor assert(Filename && "No file name to adjust?"); 735b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 736b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor if (!isysroot) 737b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor return Filename; 738b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 739b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor // Verify that the filename and the system root have the same prefix. 740b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor unsigned Pos = 0; 741b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor for (; Filename[Pos] && isysroot[Pos]; ++Pos) 742e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne if (Filename[Pos] != isysroot[Pos]) 7430558df2da807646e65d4fa290f4e92114af1a746Chris Lattner return Filename; // Prefixes don't match. 744b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 7451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // We hit the end of the filename before we hit the end of the system root. 746a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl if (!Filename[Pos]) 747b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner return Filename; 748b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // If the file name has a '/' at the current position, skip over the '/'. 7508538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl // We distinguish sysroot-based includes from absolute includes by the 7518538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl // absence of '/' at the beginning of sysroot-based includes. 7521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Filename[Pos] == '/') 7533397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl ++Pos; 754f29f0a28c4d9599b389bbb6d186e14af753dc5a3Sebastian Redl 75551e774d42269e3b22d746184c0b9076fc13b32e6Zhongxing Xu return Filename + Pos; 75631d375f056447d4e2418275d4913661d3bfedb3eDouglas Gregor} 757b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 758b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner/// \brief Write the AST metadata (e.g., i686-apple-darwin9). 759b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattnervoid ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot) { 760ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor using namespace llvm; 761b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 762b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner // Metadata 763b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner const TargetInfo &Target = Context.Target; 764b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev(); 765b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner MetaAbbrev->Add(BitCodeAbbrevOp( 766b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Chain ? CHAINED_METADATA : METADATA)); 76749b96d1a382ae9f31456166f1a734d3f7f30b992Argyrios Kyrtzidis MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major 768b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor 769b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major 770b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor 771b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable 7727f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor // Target triple or chained PCH name 7737f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 7744fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev); 775b81c17092039f39be60e9656a37cffbdf2e2c783Douglas Gregor 7765b4ec636637c9d876102240127cc0dca9280e83aTed Kremenek RecordData Record; 777e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis Record.push_back(Chain ? CHAINED_METADATA : METADATA); 778e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor Record.push_back(VERSION_MAJOR); 779320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian Record.push_back(VERSION_MINOR); 780b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(CLANG_VERSION_MAJOR); 781b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(CLANG_VERSION_MINOR); 782b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(isysroot != 0); 783b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor // FIXME: This writes the absolute path for chained headers. 784b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple(); 785b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr); 786b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 787b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor // Original file name 788b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor SourceManager &SM = Context.getSourceManager(); 789b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { 790b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev(); 79184bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE_NAME)); 792cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 793837593fec8389eea3143920d7f2180b079b609e8Douglas Gregor unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev); 79484bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne 79584bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne llvm::sys::Path MainFilePath(MainFile->getName()); 796ebcbe1d3dc7d4f0c1f540a632fa0684dd0a857d5Sean Hunt 797d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor MainFilePath.makeAbsolute(); 798d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor 799837593fec8389eea3143920d7f2180b079b609e8Douglas Gregor const char *MainFileNameStr = MainFilePath.c_str(); 800837593fec8389eea3143920d7f2180b079b609e8Douglas Gregor MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, 801cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor isysroot); 802b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RecordData Record; 8032f4efd10c805cb779618c1a22a35eb07b5043c4eChris Lattner Record.push_back(ORIGINAL_FILE_NAME); 804b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); 805b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner } 806b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 807f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth // Repository branch/version information. 8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev(); 809b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RepoAbbrev->Add(BitCodeAbbrevOp(VERSION_CONTROL_BRANCH_REVISION)); 8102f4efd10c805cb779618c1a22a35eb07b5043c4eChris Lattner RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag 811b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev); 812b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.clear(); 813b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(VERSION_CONTROL_BRANCH_REVISION); 814b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Stream.EmitRecordWithBlob(RepoAbbrevCode, Record, 81561d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor getClangFullRepositoryVersion()); 81661d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor} 817b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 818b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner/// \brief Write the LangOptions structure. 819b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattnervoid ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { 820b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner RecordData Record; 821b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.Trigraphs); 822b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments. 823b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers. 824b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode. 825b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc) 826b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.GNUKeywords); // Allow GNU-extension keywords 827b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'. 828b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.Digraphs); // C94, C99 and C++ 829b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants. 830b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.C99); // C99 Support 831b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.Microsoft); // Microsoft extensions. 832b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner // LangOpts.MSCVersion is ignored because all it does it set a macro, which is 833b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner // already saved elsewhere. 834b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.CPlusPlus); // C++ Support 835b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support 836b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords. 837a53d2cbe37e4be0d95b9d3e09f74eafae31fc940John McCall 838d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled. 839b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled. 840b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C 841b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor // modern abi enabled. 842b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced 843b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor // modern abi enabled. 844b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled.. 845b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 846b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings 847b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.WritableStrings); // Allow writable strings 848b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.LaxVectorConversions); 849b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.AltiVec); 850b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.Exceptions); // Support exception handling. 851b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.SjLjExceptions); 852b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 853b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime. 854b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman Record.push_back(LangOpts.Freestanding); // Freestanding implementation 8550ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin) 8560ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner 8570ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner // Whether static initializers are protected by locks. 8580ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.ThreadsafeStatics); 8590ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.POSIXThreads); 8600ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.Blocks); // block extension to C 8610ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if 8620ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner // they are unused. 8630ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.MathErrno); // Math functions must respect errno 8640ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner // (modulo the platform support). 8650ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner 8660ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.getSignedOverflowBehavior()); 8670ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.HeinousExtensions); 8680ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner 8690ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined. 8700ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be 8710ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner // defined. 8720ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as 873b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner // opposed to __DYNAMIC__). 874b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero. 8750ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner 876b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be 8770ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner // used (instead of C99 semantics). 8780ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined. 8790ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner Record.push_back(LangOpts.AccessControl); // Whether C++ access control should 8800ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner // be enabled. 881b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or 882b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor // unsigned type 883b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.ShortWChar); // force wchar_t to be unsigned short 884b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.getGCMode()); 885b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.getVisibilityMode()); 886b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.getStackProtectorMode()); 887b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.InstantiationDepth); 888b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.OpenCL); 889b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.CatchUndefined); 890b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.ElideConstructors); 891b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Record.push_back(LangOpts.SpellChecking); 892b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor Stream.EmitRecord(LANGUAGE_OPTIONS, Record); 893b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor} 894b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 895b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor//===----------------------------------------------------------------------===// 896b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor// stat cache Serialization 897b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor//===----------------------------------------------------------------------===// 898b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 899b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregornamespace { 900b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor// Trait used for the on-disk hash table of stat cache results. 901b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregorclass ASTStatCacheTrait { 902b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregorpublic: 903b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor typedef const char * key_type; 904b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor typedef key_type key_type_ref; 905b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 906b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor typedef std::pair<int, struct stat> data_type; 907b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor typedef const data_type& data_type_ref; 908b6c2b3f658df5525b9c0af606b64d304e7416c2fDouglas Gregor 909a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor static unsigned ComputeHash(const char *path) { 910a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor return llvm::HashString(path); 911a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor } 9124800a5c79023271408af49797e09be32aca93232Douglas Gregor 913f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth std::pair<unsigned,unsigned> 9144800a5c79023271408af49797e09be32aca93232Douglas Gregor EmitKeyDataLength(llvm::raw_ostream& Out, const char *path, 9154800a5c79023271408af49797e09be32aca93232Douglas Gregor data_type_ref Data) { 9164800a5c79023271408af49797e09be32aca93232Douglas Gregor unsigned StrLen = strlen(path); 917b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner clang::io::Emit16(Out, StrLen); 918b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner unsigned DataLen = 1; // result value 919b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner if (Data.first == 0) 920b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner DataLen += 4 + 4 + 2 + 8 + 8; 921b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner clang::io::Emit8(Out, DataLen); 922e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor return std::make_pair(StrLen + 1, DataLen); 923e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor } 9241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 925e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) { 926e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor Out.write(path, KeyLen); 927e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor } 928e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor 929e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor void EmitData(llvm::raw_ostream& Out, key_type_ref, 930e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor data_type_ref Data, unsigned DataLen) { 931e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor using namespace clang::io; 9321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump uint64_t Start = Out.tell(); (void)Start; 933832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor 934e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor // Result of stat() 9351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Emit8(Out, Data.first? 1 : 0); 936832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor 937e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor if (Data.first == 0) { 9381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Emit32(Out, (uint32_t) Data.second.st_ino); 939e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor Emit32(Out, (uint32_t) Data.second.st_dev); 940e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor Emit16(Out, (uint16_t) Data.second.st_mode); 941832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor Emit64(Out, (uint64_t) Data.second.st_mtime); 942e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor Emit64(Out, (uint64_t) Data.second.st_size); 943e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor } 9441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 945e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor assert(Out.tell() - Start == DataLen && "Wrong data length"); 946e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor } 947e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor}; 9481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end anonymous namespace 949e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor 950e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor/// \brief Write the stat() system call cache to the AST file. 951e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregorvoid ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) { 952e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor // Build the on-disk hash table containing information about every 953e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor // stat() call. 9541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump OnDiskChainedHashTableGenerator<ASTStatCacheTrait> Generator; 955e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor unsigned NumStatEntries = 0; 956e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor for (MemorizeStatCalls::iterator Stat = StatCalls.begin(), 957b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner StatEnd = StatCalls.end(); 9583397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Stat != StatEnd; ++Stat, ++NumStatEntries) { 959832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor const char *Filename = Stat->first(); 9608e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis Generator.insert(Filename, Stat->second); 9612bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor } 962b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor 963e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor // Create the on-disk hash table in a buffer. 964bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor llvm::SmallString<4096> StatCacheData; 965e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor uint32_t BucketOffset; 966e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor { 9673397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl llvm::raw_svector_ostream Out(StatCacheData); 9683397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl // Make sure that no bucket is at offset 0 969e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor clang::io::Emit32(Out, 0); 970e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor BucketOffset = Generator.Emit(Out); 971e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor } 972e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor 973e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor // Create a blob abbreviation 9741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump using namespace llvm; 975e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 976e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(STAT_CACHE)); 9778538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 9788538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 979e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 980e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev); 981832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor 982e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor // Write the stat cache 983e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor RecordData Record; 984e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor Record.push_back(STAT_CACHE); 985e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor Record.push_back(BucketOffset); 986e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor Record.push_back(NumStatEntries); 987e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str()); 988e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor} 98910bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor 99010bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor//===----------------------------------------------------------------------===// 99110bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor// Source Manager Serialization 99210bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor//===----------------------------------------------------------------------===// 99310bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor 99410bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor/// \brief Create an abbreviation for the SLocEntry that refers to a 99510bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor/// file. 99610bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregorstatic unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { 99710bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor using namespace llvm; 99810bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 99910bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY)); 100010bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 100110bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 100210bc00fd45824f9b5cd139d63af8b0f6d28aaddaDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 1003e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1004e95b9198b8b70ce0219cfb89483b41102e02dbf5Douglas Gregor // FileEntry fields. 10051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size 100631d375f056447d4e2418275d4913661d3bfedb3eDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time 1007b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor // HeaderFileInfo fields. 1008b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImport 1009b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // DirInfo 10108538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumIncludes 1011b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // ControllingMacro 1012b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 1013b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor return Stream.EmitAbbrev(Abbrev); 1014fbfd180495e7800975c6d9bdc6d24e706ef70e34Michael J. Spencer} 10151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1016fbfd180495e7800975c6d9bdc6d24e706ef70e34Michael J. Spencer/// \brief Create an abbreviation for the SLocEntry that refers to a 1017b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor/// buffer. 1018aba54a95e9d5e4dc9056abec6bb70ea777c4a7bcKovarththanan Rajaratnamstatic unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { 10191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump using namespace llvm; 1020e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1021b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY)); 10228538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1023ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbar Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 102431d375f056447d4e2418275d4913661d3bfedb3eDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 102531d375f056447d4e2418275d4913661d3bfedb3eDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 102631d375f056447d4e2418275d4913661d3bfedb3eDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob 102731d375f056447d4e2418275d4913661d3bfedb3eDouglas Gregor return Stream.EmitAbbrev(Abbrev); 1028b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor} 102911a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam 10308e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis/// \brief Create an abbreviation for the SLocEntry that refers to a 10318e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis/// buffer's blob. 10328e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidisstatic unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) { 10338e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis using namespace llvm; 10348e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 10358e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_BLOB)); 10368e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob 10378e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis return Stream.EmitAbbrev(Abbrev); 10388e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis} 10398e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis 10408e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis/// \brief Create an abbreviation for the SLocEntry that refers to an 10418e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis/// buffer. 10428e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidisstatic unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) { 10438e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis using namespace llvm; 10448e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 10458e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_INSTANTIATION_ENTRY)); 10468e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1047f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location 1048f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location 10498538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location 1050f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length 1051f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek return Stream.EmitAbbrev(Abbrev); 1052445e23e9b909ec8e21303c7dd82c90b72fc09ac4Douglas Gregor} 10538538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 1054f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek/// \brief Writes the block containing the serialized form of the 1055f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek/// source manager. 10562bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor/// 10572bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor/// TODO: We should probably use an on-disk hash table (stored in a 10582bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor/// blob), indexed based on the file name, so that we only create 1059a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl/// entries for files that we actually need. In the common case (no 10600a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor/// errors), we probably won't have to create file entries for any of 10617d5e81bf24dbfd334a7c62a7ae51043c79a69aa9Douglas Gregor/// the files in the AST. 10627d5e81bf24dbfd334a7c62a7ae51043c79a69aa9Douglas Gregorvoid ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, 10637d5e81bf24dbfd334a7c62a7ae51043c79a69aa9Douglas Gregor const Preprocessor &PP, 10647d5e81bf24dbfd334a7c62a7ae51043c79a69aa9Douglas Gregor const char *isysroot) { 10657d5e81bf24dbfd334a7c62a7ae51043c79a69aa9Douglas Gregor RecordData Record; 1066b86b8dc7ef89405205f94635c1073cdb1a7093ebDouglas Gregor 1067b86b8dc7ef89405205f94635c1073cdb1a7093ebDouglas Gregor // Enter the source manager block. 1068b86b8dc7ef89405205f94635c1073cdb1a7093ebDouglas Gregor Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 3); 10698538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 10700a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor // Abbreviations for the various kinds of source-location entries. 10710a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream); 107214f79002e58556798e86168c63e48d533287eda5Douglas Gregor unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream); 10734fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream); 10744fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor unsigned SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream); 10754fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 10764fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // Write the line table. 10774fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (SourceMgr.hasLineTable()) { 10783397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl LineTableInfo &LineTable = SourceMgr.getLineTable(); 10794fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 10804fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // Emit the file names 10814fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(LineTable.getNumFilenames()); 10821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) { 108374e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner // Emit the file name 108474e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner const char *Filename = LineTable.getFilename(I); 10854fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 10864fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor unsigned FilenameLen = Filename? strlen(Filename) : 0; 10872596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar Record.push_back(FilenameLen); 10884fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (FilenameLen) 10891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Record.insert(Record.end(), Filename, Filename + FilenameLen); 10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 10915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner 10924fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // Emit the line entries 10934fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end(); 10944fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor L != LEnd; ++L) { 109574e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner // Emit the file ID 10964fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(L->first); 10974fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 10984fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // Emit the line entries 10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Record.push_back(L->second.size()); 11005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (std::vector<LineEntry>::iterator LE = L->second.begin(), 11014fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor LEEnd = L->second.end(); 11024fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor LE != LEEnd; ++LE) { 11031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Record.push_back(LE->FileOffset); 11045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner Record.push_back(LE->LineNo); 11054fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(LE->FilenameID); 11064fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back((unsigned)LE->FileKind); 11074fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(LE->IncludeOffset); 11081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 110974e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner } 111074e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner Stream.EmitRecord(SM_LINE_TABLE, Record); 111174e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner } 111274e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner 111374e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner // Write out the source location entry table. We skip the first 11144fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // entry, which is always the same dummy entry. 11154fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor std::vector<uint32_t> SLocEntryOffsets; 11164fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor RecordData PreloadSLocs; 11174fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0; 11184fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID); 11194fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size(); 11203397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl I != N; ++I) { 1121a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl // Get this source location entry. 11224fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I); 11234fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 11243397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl // Record the offset of this source-location entry. 11254fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor SLocEntryOffsets.push_back(Stream.GetCurrentBitNo()); 11261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11274fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // Figure out which record code to use. 1128e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor unsigned Code; 11295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (SLoc->isFile()) { 11301e5f83ba515157dc7f263dc91b1d51c7a5754c35Chris Lattner if (SLoc->getFile().getContentCache()->Entry) 1131e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor Code = SM_SLOC_FILE_ENTRY; 11321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump else 11334fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Code = SM_SLOC_BUFFER_ENTRY; 11341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } else 11354fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Code = SM_SLOC_INSTANTIATION_ENTRY; 11364fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.clear(); 11374fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(Code); 11384fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 11394fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(SLoc->getOffset()); 11404fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (SLoc->isFile()) { 11414fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor const SrcMgr::FileInfo &File = SLoc->getFile(); 11424fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(File.getIncludeLoc().getRawEncoding()); 11434fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding 11444fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(File.hasLineDirectives()); 11454fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 11468538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl const SrcMgr::ContentCache *Content = File.getContentCache(); 11474fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (Content->Entry) { 11484fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // The source location entry is a file. The blob associated 11494fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // with this entry is the file name. 11504fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 11514fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // Emit size/modification time for this file. 11524fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(Content->Entry->getSize()); 11534fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(Content->Entry->getModificationTime()); 11548538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 11554fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // Emit header-search information associated with this file. 11564fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor HeaderFileInfo HFI; 1157ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbar HeaderSearch &HS = PP.getHeaderSearchInfo(); 11584fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (Content->Entry->getUID() < HS.header_file_size()) 11594fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor HFI = HS.header_file_begin()[Content->Entry->getUID()]; 11604fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Record.push_back(HFI.isImport); 116114f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.push_back(HFI.DirInfo); 116214f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.push_back(HFI.NumIncludes); 116314f79002e58556798e86168c63e48d533287eda5Douglas Gregor AddIdentifierRef(HFI.ControllingMacro, Record); 116414f79002e58556798e86168c63e48d533287eda5Douglas Gregor 116514f79002e58556798e86168c63e48d533287eda5Douglas Gregor // Turn the file name into an absolute path, if it isn't already. 1166c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor const char *Filename = Content->Entry->getName(); 116714f79002e58556798e86168c63e48d533287eda5Douglas Gregor llvm::sys::Path FilePath(Filename, strlen(Filename)); 116814f79002e58556798e86168c63e48d533287eda5Douglas Gregor FilePath.makeAbsolute(); 11698538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Filename = FilePath.c_str(); 117014f79002e58556798e86168c63e48d533287eda5Douglas Gregor 117114f79002e58556798e86168c63e48d533287eda5Douglas Gregor Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 117214f79002e58556798e86168c63e48d533287eda5Douglas Gregor Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename); 117314f79002e58556798e86168c63e48d533287eda5Douglas Gregor 11742d52be56ff595341be3c6cec337af6763804ce66Douglas Gregor // FIXME: For now, preload all file source locations, so that 11752d52be56ff595341be3c6cec337af6763804ce66Douglas Gregor // we get the appropriate File entries in the reader. This is 11762d52be56ff595341be3c6cec337af6763804ce66Douglas Gregor // a temporary measure. 1177a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); 1178d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis } else { 117910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // The source location entry is a buffer. The blob associated 118010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // with this entry contains the contents of the buffer. 118114f79002e58556798e86168c63e48d533287eda5Douglas Gregor 1182c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor // We add one to the size so that we capture the trailing NULL 118314f79002e58556798e86168c63e48d533287eda5Douglas Gregor // that is required by llvm::MemoryBuffer::getMemBuffer (on 118414f79002e58556798e86168c63e48d533287eda5Douglas Gregor // the reader side). 118514f79002e58556798e86168c63e48d533287eda5Douglas Gregor const llvm::MemoryBuffer *Buffer 118614f79002e58556798e86168c63e48d533287eda5Douglas Gregor = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); 1187c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor const char *Name = Buffer->getBufferIdentifier(); 118814f79002e58556798e86168c63e48d533287eda5Douglas Gregor Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record, 118914f79002e58556798e86168c63e48d533287eda5Douglas Gregor llvm::StringRef(Name, strlen(Name) + 1)); 11908538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.clear(); 119114f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.push_back(SM_SLOC_BUFFER_BLOB); 119214f79002e58556798e86168c63e48d533287eda5Douglas Gregor Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, 119314f79002e58556798e86168c63e48d533287eda5Douglas Gregor llvm::StringRef(Buffer->getBufferStart(), 119414f79002e58556798e86168c63e48d533287eda5Douglas Gregor Buffer->getBufferSize() + 1)); 119514f79002e58556798e86168c63e48d533287eda5Douglas Gregor 1196c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor if (strcmp(Name, "<built-in>") == 0) 119714f79002e58556798e86168c63e48d533287eda5Douglas Gregor PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); 119814f79002e58556798e86168c63e48d533287eda5Douglas Gregor } 119914f79002e58556798e86168c63e48d533287eda5Douglas Gregor } else { 120014f79002e58556798e86168c63e48d533287eda5Douglas Gregor // The source location entry is an instantiation. 1201c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation(); 120214f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.push_back(Inst.getSpellingLoc().getRawEncoding()); 120314f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.push_back(Inst.getInstantiationLocStart().getRawEncoding()); 12048538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding()); 120514f79002e58556798e86168c63e48d533287eda5Douglas Gregor 1206c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor // Compute the token length for this macro expansion. 120714f79002e58556798e86168c63e48d533287eda5Douglas Gregor unsigned NextOffset = SourceMgr.getNextOffset(); 120814f79002e58556798e86168c63e48d533287eda5Douglas Gregor if (I + 1 != N) 1209f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset(); 1210f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth Record.push_back(NextOffset - SLoc->getOffset() - 1); 1211f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record); 121214f79002e58556798e86168c63e48d533287eda5Douglas Gregor } 121314f79002e58556798e86168c63e48d533287eda5Douglas Gregor } 1214f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth 121514f79002e58556798e86168c63e48d533287eda5Douglas Gregor Stream.ExitBlock(); 121614f79002e58556798e86168c63e48d533287eda5Douglas Gregor 121714f79002e58556798e86168c63e48d533287eda5Douglas Gregor if (SLocEntryOffsets.empty()) 121814f79002e58556798e86168c63e48d533287eda5Douglas Gregor return; 1219f60e9918690fcf02974bc1ebecd42c99d561855eDouglas Gregor 1220c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor // Write the source-location offsets table into the AST block. This 122114f79002e58556798e86168c63e48d533287eda5Douglas Gregor // table is used for lazily loading source-location information. 122214f79002e58556798e86168c63e48d533287eda5Douglas Gregor using namespace llvm; 1223cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1224cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS)); 1225cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs 1226cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset 1227590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets 1228cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev); 1229b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor 1230b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor Record.clear(); 1231b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor Record.push_back(SOURCE_LOCATION_OFFSETS); 1232b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor Record.push_back(SLocEntryOffsets.size()); 1233cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor unsigned BaseOffset = Chain ? Chain->getNextSLocOffset() : 0; 1234590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis Record.push_back(SourceMgr.getNextOffset() - BaseOffset); 1235cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, 1236cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor (const char *)data(SLocEntryOffsets), 1237cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0])); 1238cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1239cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // Write the source location entry preloads array, telling the AST 1240cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // reader which source locations entries it should load eagerly. 1241cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs); 1242cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor} 1243cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1244cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor//===----------------------------------------------------------------------===// 1245cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor// Preprocessor Serialization 1246cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor//===----------------------------------------------------------------------===// 1247cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1248cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// \brief Writes the block containing the serialized form of the 1249cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// preprocessor. 1250cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// 1251cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorvoid ASTWriter::WritePreprocessor(const Preprocessor &PP) { 12525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner RecordData Record; 1253cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1254cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // If the preprocessor __COUNTER__ value has been bumped, remember it. 1255cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (PP.getCounterValue() != 0) { 1256b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor Record.push_back(PP.getCounterValue()); 1257cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Stream.EmitRecord(PP_COUNTER_VALUE, Record); 1258cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.clear(); 1259cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor } 1260cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 12615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner // Enter the preprocessor block. 1262cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3); 1263cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1264cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // If the AST file contains __DATE__ or __TIME__ emit a warning about this. 12655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner // FIXME: use diagnostics subsystem for localization etc. 1266cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (PP.SawDateOrTime()) 1267cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n"); 1268cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1269cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1270b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // Loop over all the macro definitions that are live at the end of the file, 1271b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // emitting each to the PP section. 1272b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); 1273b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor unsigned InclusionAbbrev = 0; 1274b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor if (PPRec) { 1275cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor using namespace llvm; 1276cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1277cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(PP_INCLUSION_DIRECTIVE)); 1278cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index 1279cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location 1280cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location 1281cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length 1282b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes 1283b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind 1284b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1285b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor InclusionAbbrev = Stream.EmitAbbrev(Abbrev); 1286b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor } 1287b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor 1288b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); 1289b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor I != E; ++I) { 1290b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // FIXME: This emits macros in hash table order, we should do it in a stable 1291b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // order so that output is reproducible. 1292b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor MacroInfo *MI = I->second; 1293b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor 1294b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // Don't emit builtin macros like __LINE__ to the AST file unless they have 1295b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // been redefined by the header (in which case they are not isBuiltinMacro). 1296b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // Also skip macros from a AST file if we're chaining. 1297b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor 1298b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // FIXME: There is a (probably minor) optimization we could do here, if 1299b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor // the macro comes from the original PCH but the identifier comes from a 1300cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // chained PCH, by storing the offset into the original PCH rather than 1301cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // writing the macro definition a second time. 1302b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor if (MI->isBuiltinMacro() || 1303b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor (Chain && I->first->isFromAST() && MI->isFromAST())) 1304b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor continue; 1305cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1306cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor AddIdentifierRef(I->first, Record); 1307cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor MacroOffsets[I->first] = Stream.GetCurrentBitNo(); 1308cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(MI->getDefinitionLoc().getRawEncoding()); 1309cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(MI->isUsed()); 1310cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1311cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor unsigned Code; 1312cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (MI->isObjectLike()) { 1313590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis Code = PP_MACRO_OBJECT_LIKE; 13145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner } else { 1315cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Code = PP_MACRO_FUNCTION_LIKE; 1316cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1317cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(MI->isC99Varargs()); 1318cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(MI->isGNUVarargs()); 1319cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(MI->getNumArgs()); 1320cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end(); 1321cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor I != E; ++I) 13225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner AddIdentifierRef(*I, Record); 1323cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor } 1324cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1325cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // If we have a detailed preprocessing record, record the macro definition 1326cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // ID that corresponds to this macro. 1327cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (PPRec) 1328cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(getMacroDefinitionID(PPRec->findMacroDefinition(MI))); 1329590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis 1330590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis Stream.EmitRecord(Code, Record); 1331590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis Record.clear(); 1332cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1333cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // Emit the tokens array. 1334cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) { 1335cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // Note that we know that the preprocessor does not have any annotation 1336cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // tokens in it because they are created by the parser, and thus can't be 1337cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // in a macro definition. 1338cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor const Token &Tok = MI->getReplacementToken(TokNo); 1339cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1340cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(Tok.getLocation().getRawEncoding()); 1341cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(Tok.getLength()); 1342cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1343cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // FIXME: When reading literal tokens, reconstruct the literal pointer if 1344cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // it is needed. 1345cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor AddIdentifierRef(Tok.getIdentifierInfo(), Record); 1346cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1347cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // FIXME: Should translate token kind to a stable encoding. 1348cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(Tok.getKind()); 1349cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // FIXME: Should translate token flags to a stable encoding. 1350cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(Tok.getFlags()); 1351cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1352cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Stream.EmitRecord(PP_TOKEN, Record); 1353cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.clear(); 1354cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor } 1355cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor ++NumMacros; 1356cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor } 1357cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1358cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // If the preprocessor has a preprocessing record, emit it. 1359cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor unsigned NumPreprocessingRecords = 0; 1360cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (PPRec) { 1361cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor unsigned IndexBase = Chain ? PPRec->getNumPreallocatedEntities() : 0; 1362cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor for (PreprocessingRecord::iterator E = PPRec->begin(Chain), 1363cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor EEnd = PPRec->end(Chain); 1364cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor E != EEnd; ++E) { 1365cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.clear(); 1366b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor 1367cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { 1368cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(IndexBase + NumPreprocessingRecords++); 1369cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor AddSourceLocation(MI->getSourceRange().getBegin(), Record); 1370b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor AddSourceLocation(MI->getSourceRange().getEnd(), Record); 1371cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor AddIdentifierRef(MI->getName(), Record); 1372cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Record.push_back(getMacroDefinitionID(MI->getDefinition())); 1373cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor Stream.EmitRecord(PP_MACRO_INSTANTIATION, Record); 1374cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor continue; 1375b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor } 1376b4dc485a2b38ea98ba7da01596fd0e8438120346Douglas Gregor 1377cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { 1378cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // Record this macro definition's location. 1379cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor MacroID ID = getMacroDefinitionID(MD); 1380cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 1381cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor // Don't write the macro definition if it is from another AST file. 1382cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor if (ID < FirstMacroID) 1383cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor continue; 138414f79002e58556798e86168c63e48d533287eda5Douglas Gregor 138514f79002e58556798e86168c63e48d533287eda5Douglas Gregor unsigned Position = ID - FirstMacroID; 138614f79002e58556798e86168c63e48d533287eda5Douglas Gregor if (Position != MacroDefinitionOffsets.size()) { 138714f79002e58556798e86168c63e48d533287eda5Douglas Gregor if (Position > MacroDefinitionOffsets.size()) 138814f79002e58556798e86168c63e48d533287eda5Douglas Gregor MacroDefinitionOffsets.resize(Position + 1); 138914f79002e58556798e86168c63e48d533287eda5Douglas Gregor 139014f79002e58556798e86168c63e48d533287eda5Douglas Gregor MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo(); 139114f79002e58556798e86168c63e48d533287eda5Douglas Gregor } else 1392a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); 1393e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor 1394832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor Record.push_back(IndexBase + NumPreprocessingRecords++); 13957f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Record.push_back(ID); 13967f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor AddSourceLocation(MD->getSourceRange().getBegin(), Record); 1397f04ad69fed38d26fc0d6f7d6fd0a4631ddfbc7feChris Lattner AddSourceLocation(MD->getSourceRange().getEnd(), Record); 13988538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl AddIdentifierRef(MD->getName(), Record); 139914f79002e58556798e86168c63e48d533287eda5Douglas Gregor AddSourceLocation(MD->getLocation(), Record); 140014f79002e58556798e86168c63e48d533287eda5Douglas Gregor Stream.EmitRecord(PP_MACRO_DEFINITION, Record); 1401828e18cd80319c67b9b9776d1ed5411161d9f0bfChris Lattner continue; 1402828e18cd80319c67b9b9776d1ed5411161d9f0bfChris Lattner } 1403828e18cd80319c67b9b9776d1ed5411161d9f0bfChris Lattner 1404f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { 14057f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Record.push_back(PP_INCLUSION_DIRECTIVE); 140614f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.push_back(IndexBase + NumPreprocessingRecords++); 140714f79002e58556798e86168c63e48d533287eda5Douglas Gregor AddSourceLocation(ID->getSourceRange().getBegin(), Record); 1408090d9b53e32bb30d9e74de895bb59b409bd49e00Chris Lattner AddSourceLocation(ID->getSourceRange().getEnd(), Record); 14094cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis Record.push_back(ID->getFileName().size()); 14104cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis Record.push_back(ID->wasInQuotes()); 14114cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis Record.push_back(static_cast<unsigned>(ID->getKind())); 14127f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor llvm::SmallString<64> Buffer; 1413f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Buffer += ID->getFileName(); 1414f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Buffer += ID->getFile()->getName(); 14150fa7d0b15ea2a224bfe43ac745d411f915da87ddSebastian Redl Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); 1416bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor continue; 1417f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 141811a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam } 14197f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor } 14207f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 14217f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Stream.ExitBlock(); 142214f79002e58556798e86168c63e48d533287eda5Douglas Gregor 142314f79002e58556798e86168c63e48d533287eda5Douglas Gregor // Write the offsets table for the preprocessing record. 142414f79002e58556798e86168c63e48d533287eda5Douglas Gregor if (NumPreprocessingRecords > 0) { 1425a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor // Write the offsets table for identifier IDs. 1426a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor using namespace llvm; 14278538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 14284cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis Abbrev->Add(BitCodeAbbrevOp(MACRO_DEFINITION_OFFSETS)); 14294cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of records 14308538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs 143114f79002e58556798e86168c63e48d533287eda5Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1432f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 14337f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 143414f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.clear(); 143514f79002e58556798e86168c63e48d533287eda5Douglas Gregor Record.push_back(MACRO_DEFINITION_OFFSETS); 1436f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Record.push_back(NumPreprocessingRecords); 1437f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Record.push_back(MacroDefinitionOffsets.size()); 143814f79002e58556798e86168c63e48d533287eda5Douglas Gregor Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record, 143914f79002e58556798e86168c63e48d533287eda5Douglas Gregor (const char *)data(MacroDefinitionOffsets), 144014f79002e58556798e86168c63e48d533287eda5Douglas Gregor MacroDefinitionOffsets.size() * sizeof(uint32_t)); 144114f79002e58556798e86168c63e48d533287eda5Douglas Gregor } 1442bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor} 144314f79002e58556798e86168c63e48d533287eda5Douglas Gregor 144414f79002e58556798e86168c63e48d533287eda5Douglas Gregor//===----------------------------------------------------------------------===// 1445b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis// Type Serialization 1446b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 1447a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor 1448b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis/// \brief Write the representation of a type to the AST stream. 144914f79002e58556798e86168c63e48d533287eda5Douglas Gregorvoid ASTWriter::WriteType(QualType T) { 145014f79002e58556798e86168c63e48d533287eda5Douglas Gregor TypeIdx &Idx = TypeIdxs[T]; 14511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Idx.getIndex() == 0) // we haven't seen this type before. 14522d52be56ff595341be3c6cec337af6763804ce66Douglas Gregor Idx = TypeIdx(NextTypeID++); 1453b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 1454b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); 1455a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor 1456d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // Record the offset for this type. 145710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis unsigned Index = Idx.getIndex() - FirstTypeID; 145810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis if (TypeOffsets.size() == Index) 145910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis TypeOffsets.push_back(Stream.GetCurrentBitNo()); 146010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis else if (TypeOffsets.size() < Index) { 146110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis TypeOffsets.resize(Index + 1); 146210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis TypeOffsets[Index] = Stream.GetCurrentBitNo(); 146310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis } 146410f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 146510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis RecordData Record; 1466a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor 1467e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor // Emit the type's representation. 1468b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ASTTypeWriter W(*this, Record); 1469fbfd180495e7800975c6d9bdc6d24e706ef70e34Michael J. Spencer 14702c10c8072cabeb22651462e435e8b81f3221b6a5Anders Carlsson if (T.hasLocalNonFastQualifiers()) { 14712c10c8072cabeb22651462e435e8b81f3221b6a5Anders Carlsson Qualifiers Qs = T.getLocalQualifiers(); 14722c10c8072cabeb22651462e435e8b81f3221b6a5Anders Carlsson AddTypeRef(T.getLocalUnqualifiedType(), Record); 14732c10c8072cabeb22651462e435e8b81f3221b6a5Anders Carlsson Record.push_back(Qs.getAsOpaqueValue()); 14742c10c8072cabeb22651462e435e8b81f3221b6a5Anders Carlsson W.Code = TYPE_EXT_QUAL; 14752c10c8072cabeb22651462e435e8b81f3221b6a5Anders Carlsson } else { 14762c10c8072cabeb22651462e435e8b81f3221b6a5Anders Carlsson switch (T->getTypeClass()) { 1477fbfd180495e7800975c6d9bdc6d24e706ef70e34Michael J. Spencer // For all of the concrete, non-dependent types, call the 1478aba54a95e9d5e4dc9056abec6bb70ea777c4a7bcKovarththanan Rajaratnam // appropriate visitor function. 14791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#define TYPE(Class, Base) \ 1480e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break; 1481ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbar#define ABSTRACT_TYPE(Class, Base) 1482a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor#include "clang/AST/TypeNodes.def" 1483a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor } 1484a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor } 1485a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor 1486a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor // Emit the serialized record. 1487a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor Stream.EmitRecord(W.Code, Record); 1488a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor 1489a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor // Flush any expressions that were written as part of this type. 1490a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor FlushStmts(); 1491a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor} 149214f79002e58556798e86168c63e48d533287eda5Douglas Gregor 149314f79002e58556798e86168c63e48d533287eda5Douglas Gregor//===----------------------------------------------------------------------===// 149414f79002e58556798e86168c63e48d533287eda5Douglas Gregor// Declaration Serialization 149514f79002e58556798e86168c63e48d533287eda5Douglas Gregor//===----------------------------------------------------------------------===// 149614f79002e58556798e86168c63e48d533287eda5Douglas Gregor 149714f79002e58556798e86168c63e48d533287eda5Douglas Gregor/// \brief Write the block containing all of the declaration IDs 149814f79002e58556798e86168c63e48d533287eda5Douglas Gregor/// lexically declared within the given DeclContext. 149936c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor/// 1500e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the 150114f79002e58556798e86168c63e48d533287eda5Douglas Gregor/// bistream, or 0 if no block was written. 1502ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbaruint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, 15035f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner DeclContext *DC) { 150414f79002e58556798e86168c63e48d533287eda5Douglas Gregor if (DC->decls_empty()) 15058538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl return 0; 1506c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor 15075f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner uint64_t Offset = Stream.GetCurrentBitNo(); 1508ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbar RecordData Record; 15097f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Record.push_back(DECL_CONTEXT_LEXICAL); 1510f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor llvm::SmallVector<KindDeclIDPair, 64> Decls; 1511f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); 1512f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor D != DEnd; ++D) 151314f79002e58556798e86168c63e48d533287eda5Douglas Gregor Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D))); 151414f79002e58556798e86168c63e48d533287eda5Douglas Gregor 1515f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth ++NumLexicalDeclContexts; 15161728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, 151778df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth reinterpret_cast<char*>(Decls.data()), 151878df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth Decls.size() * sizeof(KindDeclIDPair)); 1519d21683cdc0ff4217bfd98a9d8d0c1083b642caacArgyrios Kyrtzidis return Offset; 1520d21683cdc0ff4217bfd98a9d8d0c1083b642caacArgyrios Kyrtzidis} 152114f79002e58556798e86168c63e48d533287eda5Douglas Gregor 1522f60e9918690fcf02974bc1ebecd42c99d561855eDouglas Gregorvoid ASTWriter::WriteTypeDeclOffsets() { 1523f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor using namespace llvm; 1524bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor RecordData Record; 1525f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1526f60e9918690fcf02974bc1ebecd42c99d561855eDouglas Gregor // Write the type offsets array 1527f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 152814f79002e58556798e86168c63e48d533287eda5Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET)); 152914f79002e58556798e86168c63e48d533287eda5Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types 153014f79002e58556798e86168c63e48d533287eda5Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block 15317f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1532bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor Record.clear(); 15337f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Record.push_back(TYPE_OFFSET); 15347f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Record.push_back(TypeOffsets.size()); 15352eafc1b56347f772729e082e6bac824b0ef1b585Douglas Gregor Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, 15363397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl (const char *)data(TypeOffsets), 15377f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor TypeOffsets.size() * sizeof(TypeOffsets[0])); 15387f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 15397f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor // Write the declaration offsets array 15408538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abbrev = new BitCodeAbbrev(); 15417f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); 1542f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations 15437f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block 15447f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 15451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Record.clear(); 15467f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Record.push_back(DECL_OFFSET); 15478538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.push_back(DeclOffsets.size()); 15487f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, 1549f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor (const char *)data(DeclOffsets), 15506e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer DeclOffsets.size() * sizeof(DeclOffsets[0])); 15517f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor} 15524cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis 15534cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 15544cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis// Global Method Pool and Selector Serialization 15554cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 15564cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis 15574cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidisnamespace { 15584cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis// Trait used for the on-disk hash table used in the method pool. 15594cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidisclass ASTMethodPoolTrait { 15604cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis ASTWriter &Writer; 15614cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis 15624cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidispublic: 15634cdb0e2a2e9d93805e5ceaf8bc7018bdd166aec1Argyrios Kyrtzidis typedef Selector key_type; 15643397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl typedef key_type key_type_ref; 15657f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 15668538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl struct data_type { 1567f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SelectorID ID; 1568f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ObjCMethodList Instance, Factory; 1569f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor }; 1570f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor typedef const data_type& data_type_ref; 1571f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1572f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { } 1573f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1574f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor static unsigned ComputeHash(Selector Sel) { 1575f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return serialization::ComputeHash(Sel); 1576f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1577f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1578f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor std::pair<unsigned,unsigned> 1579f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel, 1580f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor data_type_ref Methods) { 1581f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4); 1582f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor clang::io::Emit16(Out, KeyLen); 1583f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts 1584f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (const ObjCMethodList *Method = &Methods.Instance; Method; 1585f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Method = Method->Next) 1586f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (Method->Method) 1587f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor DataLen += 4; 1588f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (const ObjCMethodList *Method = &Methods.Factory; Method; 1589f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Method = Method->Next) 1590f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (Method->Method) 1591f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor DataLen += 4; 1592f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor clang::io::Emit16(Out, DataLen); 1593f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return std::make_pair(KeyLen, DataLen); 1594f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1595f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1596f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) { 1597f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor uint64_t Start = Out.tell(); 1598f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert((Start >> 32) == 0 && "Selector key offset too large"); 1599f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Writer.SetSelectorOffset(Sel, Start); 1600f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned N = Sel.getNumArgs(); 1601f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor clang::io::Emit16(Out, N); 1602f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (N == 0) 1603f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor N = 1; 1604f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0; I != N; ++I) 1605f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor clang::io::Emit32(Out, 1606f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I))); 1607f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1608f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1609f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor void EmitData(llvm::raw_ostream& Out, key_type_ref, 161014f79002e58556798e86168c63e48d533287eda5Douglas Gregor data_type_ref Methods, unsigned DataLen) { 161114f79002e58556798e86168c63e48d533287eda5Douglas Gregor uint64_t Start = Out.tell(); (void)Start; 16124fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor clang::io::Emit32(Out, Methods.ID); 16134fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor unsigned NumInstanceMethods = 0; 16144fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor for (const ObjCMethodList *Method = &Methods.Instance; Method; 16154fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Method = Method->Next) 16169c7361006b8cd95333958150dd0c803261807b68Douglas Gregor if (Method->Method) 16179c7361006b8cd95333958150dd0c803261807b68Douglas Gregor ++NumInstanceMethods; 16189c7361006b8cd95333958150dd0c803261807b68Douglas Gregor 16199c7361006b8cd95333958150dd0c803261807b68Douglas Gregor unsigned NumFactoryMethods = 0; 16209c7361006b8cd95333958150dd0c803261807b68Douglas Gregor for (const ObjCMethodList *Method = &Methods.Factory; Method; 16219c7361006b8cd95333958150dd0c803261807b68Douglas Gregor Method = Method->Next) 16229c7361006b8cd95333958150dd0c803261807b68Douglas Gregor if (Method->Method) 16239c7361006b8cd95333958150dd0c803261807b68Douglas Gregor ++NumFactoryMethods; 16240b1fb988012da21d996c43e36867787a7a07b889Chris Lattner 16250b1fb988012da21d996c43e36867787a7a07b889Chris Lattner clang::io::Emit16(Out, NumInstanceMethods); 16260b1fb988012da21d996c43e36867787a7a07b889Chris Lattner clang::io::Emit16(Out, NumFactoryMethods); 16277143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor for (const ObjCMethodList *Method = &Methods.Instance; Method; 1628e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis Method = Method->Next) 1629e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis if (Method->Method) 1630e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 1631e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis for (const ObjCMethodList *Method = &Methods.Factory; Method; 16327c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner Method = Method->Next) 16337c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner if (Method->Method) 1634c1f9d828c733ec1eba06d01070735d1f36fda733Chris Lattner clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 1635c1f9d828c733ec1eba06d01070735d1f36fda733Chris Lattner 1636c1f9d828c733ec1eba06d01070735d1f36fda733Chris Lattner assert(Out.tell() - Start == DataLen && "Data length is wrong"); 16378538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl } 1638c1f9d828c733ec1eba06d01070735d1f36fda733Chris Lattner}; 16392eafc1b56347f772729e082e6bac824b0ef1b585Douglas Gregor} // end anonymous namespace 16402eafc1b56347f772729e082e6bac824b0ef1b585Douglas Gregor 16412eafc1b56347f772729e082e6bac824b0ef1b585Douglas Gregor/// \brief Write ObjC data: selectors and the method pool. 1642ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor/// 16431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// The method pool contains both instance and factory methods, stored 16443397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl/// in an on-disk hash table indexed by the selector. The hash table also 16452eafc1b56347f772729e082e6bac824b0ef1b585Douglas Gregor/// contains an empty entry for every other selector known to Sema. 16462eafc1b56347f772729e082e6bac824b0ef1b585Douglas Gregorvoid ASTWriter::WriteSelectors(Sema &SemaRef) { 16472eafc1b56347f772729e082e6bac824b0ef1b585Douglas Gregor using namespace llvm; 16481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1649ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor // Do we have to do anything at all? 16507c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner if (SemaRef.MethodPool.empty() && SelectorIDs.empty()) 16517c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner return; 165220249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer unsigned NumTableEntries = 0; 16539c7361006b8cd95333958150dd0c803261807b68Douglas Gregor // Create and write out the blob that contains selectors and the method pool. 16545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner { 16559c7361006b8cd95333958150dd0c803261807b68Douglas Gregor OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator; 16569c7361006b8cd95333958150dd0c803261807b68Douglas Gregor ASTMethodPoolTrait Trait(*this); 1657040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor 1658040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor // Create the on-disk hash table representation. We walk through every 16597c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner // selector we've seen and look it up in the method pool. 1660aa93a875605536d72a10359a0098396192b7d4ecDouglas Gregor SelectorOffsets.resize(NextSelectorID - FirstSelectorID); 16617143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor for (llvm::DenseMap<Selector, SelectorID>::iterator 16627143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor I = SelectorIDs.begin(), E = SelectorIDs.end(); 16637143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor I != E; ++I) { 16649c7361006b8cd95333958150dd0c803261807b68Douglas Gregor Selector S = I->first; 16659c7361006b8cd95333958150dd0c803261807b68Douglas Gregor Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); 16669c7361006b8cd95333958150dd0c803261807b68Douglas Gregor ASTMethodPoolTrait::data_type Data = { 16679c7361006b8cd95333958150dd0c803261807b68Douglas Gregor I->second, 16689c7361006b8cd95333958150dd0c803261807b68Douglas Gregor ObjCMethodList(), 16699c7361006b8cd95333958150dd0c803261807b68Douglas Gregor ObjCMethodList() 16709c7361006b8cd95333958150dd0c803261807b68Douglas Gregor }; 1671040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor if (F != SemaRef.MethodPool.end()) { 1672040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor Data.Instance = F->second.first; 1673040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor Data.Factory = F->second.second; 1674040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor } 1675040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor // Only write this selector if it's not in an existing AST or something 1676040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor // changed. 1677040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor if (Chain && I->second < FirstSelectorID) { 1678040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor // Selector already exists. Did it change? 1679040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor bool changed = false; 16809c7361006b8cd95333958150dd0c803261807b68Douglas Gregor for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method; 16819c7361006b8cd95333958150dd0c803261807b68Douglas Gregor M = M->Next) { 16829c7361006b8cd95333958150dd0c803261807b68Douglas Gregor if (M->Method->getPCHLevel() == 0) 1683040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor changed = true; 1684040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor } 1685040a804f852c45c8b8c371ce1d421fd4cd84b6fbDouglas Gregor for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method; 16863397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl M = M->Next) { 16877c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner if (M->Method->getPCHLevel() == 0) 16883397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl changed = true; 1689ee9b0ba29094eb177a285e726ab96e979e5b9c61Douglas Gregor } 1690ee9b0ba29094eb177a285e726ab96e979e5b9c61Douglas Gregor if (!changed) 1691ee9b0ba29094eb177a285e726ab96e979e5b9c61Douglas Gregor continue; 1692ee9b0ba29094eb177a285e726ab96e979e5b9c61Douglas Gregor } else if (Data.Instance.Method || Data.Factory.Method) { 1693ee9b0ba29094eb177a285e726ab96e979e5b9c61Douglas Gregor // A new method pool entry. 169420249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer ++NumTableEntries; 1695eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 1696eee242ff426bf79149f221798966e58688383c1eDouglas Gregor Generator.insert(S, Data, Trait); 1697eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 16987c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner 16997c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner // Create the on-disk hash table in a buffer. 17009c7361006b8cd95333958150dd0c803261807b68Douglas Gregor llvm::SmallString<4096> MethodPool; 17019c7361006b8cd95333958150dd0c803261807b68Douglas Gregor uint32_t BucketOffset; 17027c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner { 17037c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner ASTMethodPoolTrait Trait(*this); 1704aa93a875605536d72a10359a0098396192b7d4ecDouglas Gregor llvm::raw_svector_ostream Out(MethodPool); 1705aa93a875605536d72a10359a0098396192b7d4ecDouglas Gregor // Make sure that no bucket is at offset 0 17067c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner clang::io::Emit32(Out, 0); 17077c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner BucketOffset = Generator.Emit(Out, Trait); 17088538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl } 17097c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner 17108538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl // Create a blob abbreviation 17111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 17127c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL)); 17137c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 17147c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 17157c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 17167c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev); 17177356a31327be9b3c3434a0c88746028980da5684Chris Lattner 17187c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner // Write the method pool 171920249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer RecordData Record; 17206a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor Record.push_back(METHOD_POOL); 17216a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor Record.push_back(BucketOffset); 17226a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor Record.push_back(NumTableEntries); 1723e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str()); 172420249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer 1725c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor // Create a blob abbreviation for the selector table offsets. 17267c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner Abbrev = new BitCodeAbbrev(); 1727f04ad69fed38d26fc0d6f7d6fd0a4631ddfbc7feChris Lattner Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS)); 1728df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index 1729df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1730df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1731df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner 1732df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner // Write the selector offsets table. 1733df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner Record.clear(); 17341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Record.push_back(SELECTOR_OFFSETS); 1735df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner Record.push_back(SelectorOffsets.size()); 1736df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, 1737df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner (const char *)data(SelectorOffsets), 1738df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner SelectorOffsets.size() * 4); 1739df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner } 17407356a31327be9b3c3434a0c88746028980da5684Chris Lattner} 1741df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner 1742df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner/// \brief Write the selectors referenced in @selector expression into AST file. 1743df961c28f84666051ad59d2da1f44023f6366d02Chris Lattnervoid ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { 1744df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner using namespace llvm; 17451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (SemaRef.ReferencedSelectors.empty()) 17468538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl return; 1747df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner 1748df961c28f84666051ad59d2da1f44023f6366d02Chris Lattner RecordData Record; 174937e2684abfe38207fdb90620da062bb18c23f29aDouglas Gregor 17507c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner // Note: this writes out all references even for a dependent AST. But it is 17514800a5c79023271408af49797e09be32aca93232Douglas Gregor // very tricky to fix, and given that @selector shouldn't really appear in 17524800a5c79023271408af49797e09be32aca93232Douglas Gregor // headers, probably not worth it. It's not a correctness issue. 17534800a5c79023271408af49797e09be32aca93232Douglas Gregor for (DenseMap<Selector, SourceLocation>::iterator S = 17544800a5c79023271408af49797e09be32aca93232Douglas Gregor SemaRef.ReferencedSelectors.begin(), 1755b6441ef9b7285bd1aa77b05b10f473f7a3f413e7Argyrios Kyrtzidis E = SemaRef.ReferencedSelectors.end(); S != E; ++S) { 17564800a5c79023271408af49797e09be32aca93232Douglas Gregor Selector Sel = (*S).first; 1757e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis SourceLocation Loc = (*S).second; 17582dbaca748bc3eb6539f417bd8354c930bdf88fa4Argyrios Kyrtzidis AddSelectorRef(Sel, Record); 1759e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis AddSourceLocation(Loc, Record); 17604800a5c79023271408af49797e09be32aca93232Douglas Gregor } 17614800a5c79023271408af49797e09be32aca93232Douglas Gregor Stream.EmitRecord(REFERENCED_SELECTOR_POOL, Record); 176220249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer} 17636a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor 17646a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor//===----------------------------------------------------------------------===// 17654800a5c79023271408af49797e09be32aca93232Douglas Gregor// Identifier Table Serialization 17664800a5c79023271408af49797e09be32aca93232Douglas Gregor//===----------------------------------------------------------------------===// 17674800a5c79023271408af49797e09be32aca93232Douglas Gregor 17684800a5c79023271408af49797e09be32aca93232Douglas Gregornamespace { 17694800a5c79023271408af49797e09be32aca93232Douglas Gregorclass ASTIdentifierTableTrait { 17704800a5c79023271408af49797e09be32aca93232Douglas Gregor ASTWriter &Writer; 17714800a5c79023271408af49797e09be32aca93232Douglas Gregor Preprocessor &PP; 17724800a5c79023271408af49797e09be32aca93232Douglas Gregor 17734800a5c79023271408af49797e09be32aca93232Douglas Gregor /// \brief Determines whether this is an "interesting" identifier 17744800a5c79023271408af49797e09be32aca93232Douglas Gregor /// that needs a full IdentifierInfo structure written into the hash 17754800a5c79023271408af49797e09be32aca93232Douglas Gregor /// table. 17764800a5c79023271408af49797e09be32aca93232Douglas Gregor static bool isInterestingIdentifier(const IdentifierInfo *II) { 17774800a5c79023271408af49797e09be32aca93232Douglas Gregor return II->isPoisoned() || 17784800a5c79023271408af49797e09be32aca93232Douglas Gregor II->isExtensionToken() || 1779272b6bc6a6c8fc04f951ad850df68c44d137f513Douglas Gregor II->hasMacroDefinition() || 1780272b6bc6a6c8fc04f951ad850df68c44d137f513Douglas Gregor II->getObjCOrBuiltinID() || 1781272b6bc6a6c8fc04f951ad850df68c44d137f513Douglas Gregor II->getFETokenInfo<void>(); 1782272b6bc6a6c8fc04f951ad850df68c44d137f513Douglas Gregor } 17834800a5c79023271408af49797e09be32aca93232Douglas Gregor 1784b6441ef9b7285bd1aa77b05b10f473f7a3f413e7Argyrios Kyrtzidispublic: 1785b6441ef9b7285bd1aa77b05b10f473f7a3f413e7Argyrios Kyrtzidis typedef const IdentifierInfo* key_type; 17867338a922dd1164002922163200b18a2c24eb0209Douglas Gregor typedef key_type key_type_ref; 17877338a922dd1164002922163200b18a2c24eb0209Douglas Gregor 17884800a5c79023271408af49797e09be32aca93232Douglas Gregor typedef IdentID data_type; 178920249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer typedef data_type data_type_ref; 17902dbaca748bc3eb6539f417bd8354c930bdf88fa4Argyrios Kyrtzidis 17912dbaca748bc3eb6539f417bd8354c930bdf88fa4Argyrios Kyrtzidis ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP) 1792e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis : Writer(Writer), PP(PP) { } 17934800a5c79023271408af49797e09be32aca93232Douglas Gregor 1794e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis static unsigned ComputeHash(const IdentifierInfo* II) { 1795e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis return llvm::HashString(II->getName()); 17964800a5c79023271408af49797e09be32aca93232Douglas Gregor } 17974800a5c79023271408af49797e09be32aca93232Douglas Gregor 17984800a5c79023271408af49797e09be32aca93232Douglas Gregor std::pair<unsigned,unsigned> 17994800a5c79023271408af49797e09be32aca93232Douglas Gregor EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II, 18004800a5c79023271408af49797e09be32aca93232Douglas Gregor IdentID ID) { 18014800a5c79023271408af49797e09be32aca93232Douglas Gregor unsigned KeyLen = II->getLength() + 1; 18029e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth unsigned DataLen = 4; // 4 bytes for the persistent ID << 1 18038f7c540ac42370c40ebcdc4b69018c938faf94ecArgyrios Kyrtzidis if (isInterestingIdentifier(II)) { 18048f7c540ac42370c40ebcdc4b69018c938faf94ecArgyrios Kyrtzidis DataLen += 2; // 2 bytes for builtin ID, flags 18058f7c540ac42370c40ebcdc4b69018c938faf94ecArgyrios Kyrtzidis if (II->hasMacroDefinition() && 18068f7c540ac42370c40ebcdc4b69018c938faf94ecArgyrios Kyrtzidis !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro()) 1807e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis DataLen += 4; 1808f70d12dbd49fcc25f1dfc0127217112ae76bcb8fChandler Carruth for (IdentifierResolver::iterator D = IdentifierResolver::begin(II), 18094800a5c79023271408af49797e09be32aca93232Douglas Gregor DEnd = IdentifierResolver::end(); 18106a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor D != DEnd; ++D) 181120249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer DataLen += sizeof(DeclID); 18124800a5c79023271408af49797e09be32aca93232Douglas Gregor } 18134800a5c79023271408af49797e09be32aca93232Douglas Gregor clang::io::Emit16(Out, DataLen); 18144800a5c79023271408af49797e09be32aca93232Douglas Gregor // We emit the key length after the data length so that every 18154800a5c79023271408af49797e09be32aca93232Douglas Gregor // string is preceded by a 16-bit length. This matches the PTH 18164800a5c79023271408af49797e09be32aca93232Douglas Gregor // format for storing identifiers. 18174800a5c79023271408af49797e09be32aca93232Douglas Gregor clang::io::Emit16(Out, KeyLen); 18184800a5c79023271408af49797e09be32aca93232Douglas Gregor return std::make_pair(KeyLen, DataLen); 18194800a5c79023271408af49797e09be32aca93232Douglas Gregor } 18204800a5c79023271408af49797e09be32aca93232Douglas Gregor 18214800a5c79023271408af49797e09be32aca93232Douglas Gregor void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II, 18224800a5c79023271408af49797e09be32aca93232Douglas Gregor unsigned KeyLen) { 18234800a5c79023271408af49797e09be32aca93232Douglas Gregor // Record the location of the key data. This is used when generating 18244800a5c79023271408af49797e09be32aca93232Douglas Gregor // the mapping from persistent IDs to strings. 18254800a5c79023271408af49797e09be32aca93232Douglas Gregor Writer.SetIdentifierOffset(II, Out.tell()); 1826c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor Out.write(II->getNameStart(), KeyLen); 182720249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer } 18286a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor 18296a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II, 1830e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis IdentID ID, unsigned) { 1831e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis if (!isInterestingIdentifier(II)) { 18326a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor clang::io::Emit32(Out, ID << 1); 18336a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor return; 18346a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor } 1835e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis 1836272b6bc6a6c8fc04f951ad850df68c44d137f513Douglas Gregor clang::io::Emit32(Out, (ID << 1) | 0x01); 18376a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor uint32_t Bits = 0; 1838e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis bool hasMacroDefinition = 183920249a1af2e462dcafdd6a350f1c7967b264ff25Michael J. Spencer II->hasMacroDefinition() && 18406a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro(); 1841e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis Bits = (uint32_t)II->getObjCOrBuiltinID(); 1842272b6bc6a6c8fc04f951ad850df68c44d137f513Douglas Gregor Bits = (Bits << 1) | unsigned(hasMacroDefinition); 1843e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis Bits = (Bits << 1) | unsigned(II->isExtensionToken()); 1844e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis Bits = (Bits << 1) | unsigned(II->isPoisoned()); 18456a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier()); 18460b1fb988012da21d996c43e36867787a7a07b889Chris Lattner Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword()); 18470b1fb988012da21d996c43e36867787a7a07b889Chris Lattner clang::io::Emit16(Out, Bits); 1848e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 1849e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor if (hasMacroDefinition) 1850e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor clang::io::Emit32(Out, Writer.getMacroOffset(II)); 1851e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 1852e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Emit the declaration IDs in reverse order, because the 1853e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // IdentifierResolver provides the declarations as they would be 1854e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // visible (e.g., the function "stat" would come before the struct 1855e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // "stat"), but IdentifierResolver::AddDeclToIdentifierChain() 185626ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor // adds declarations to the end of the list (so we need to see the 185726ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor // struct "status" before the function "status"). 185826ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor // Only emit declarations that aren't from a chained PCH, though. 185926ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II), 186026ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor IdentifierResolver::end()); 186126ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(), 186226ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor DEnd = Decls.rend(); 186326ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor D != DEnd; ++D) 186426ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor clang::io::Emit32(Out, Writer.getDeclID(*D)); 186526ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor } 186626ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor}; 186726ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor} // end anonymous namespace 18681a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor 18694bc8738d837e5d401235f99e55277338e20e3651Douglas Gregor/// \brief Write the identifier table into the AST file. 187055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor/// 187155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor/// The identifier table consists of a blob containing string data 187255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor/// (the actual identifiers themselves) and a separate "offsets" index 187355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor/// that maps identifier IDs to locations within the blob. 187455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregorvoid ASTWriter::WriteIdentifierTable(Preprocessor &PP) { 187555988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor using namespace llvm; 187655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 187755988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // Create and write out the blob that contains the identifier 187855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // strings. 187955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor { 188055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; 188155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor ASTIdentifierTableTrait Trait(*this, PP); 188255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 188355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // Look for any identifiers that were named while processing the 188455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // headers, but are otherwise not needed. We add these to the hash 1885392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // table to enable checking of the predefines buffer in the case 1886392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // where the user adds new macro definitions when building the AST 1887392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // file. 1888392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(), 1889392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor IDEnd = PP.getIdentifierTable().end(); 1890392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor ID != IDEnd; ++ID) 1891392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor getIdentifierRef(ID->second); 1892e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 1893392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Create the on-disk hash table representation. We only store offsets 1894392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // for identifiers that appear here for the first time. 1895392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor IdentifierOffsets.resize(NextIdentID - FirstIdentID); 18961e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor for (llvm::DenseMap<const IdentifierInfo *, IdentID>::iterator 18971e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end(); 18981e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor ID != IDEnd; ++ID) { 1899392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor assert(ID->first && "NULL identifier in identifier table"); 1900392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor if (!Chain || !ID->first->isFromAST()) 1901392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Generator.insert(ID->first, ID->second, Trait); 1902392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor } 190377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 1904392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Create the on-disk hash table in a buffer. 1905392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor llvm::SmallString<4096> IdentifierTable; 1906392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor uint32_t BucketOffset; 1907392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor { 1908392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor ASTIdentifierTableTrait Trait(*this, PP); 1909392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor llvm::raw_svector_ostream Out(IdentifierTable); 1910392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Make sure that no bucket is at offset 0 191177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor clang::io::Emit32(Out, 0); 191277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor BucketOffset = Generator.Emit(Out, Trait); 191377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 191477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 191577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Create a blob abbreviation 191677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 191726ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE)); 191826ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 191926ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 192026ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev); 192126ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor 192226ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor // Write the identifier table 1923392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor RecordData Record; 19241a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor Record.push_back(IDENTIFIER_TABLE); 1925392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Record.push_back(BucketOffset); 1926392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str()); 19271a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor } 1928392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 1929e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Write the offsets table for identifier IDs. 1930392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1931392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET)); 1932392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers 1933392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1934e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1935392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 1936392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor RecordData Record; 1937392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Record.push_back(IDENTIFIER_OFFSET); 1938392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Record.push_back(IdentifierOffsets.size()); 1939392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, 1940392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor (const char *)data(IdentifierOffsets), 1941392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor IdentifierOffsets.size() * sizeof(uint32_t)); 1942392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor} 19431e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 19441e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor//===----------------------------------------------------------------------===// 19451e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor// DeclContext's Name Lookup Table Serialization 1946392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor//===----------------------------------------------------------------------===// 1947392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 1948392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregornamespace { 194910694cee2588442bee1e717f5042c58ffee25279Douglas Gregor// Trait used for the on-disk hash table used in the method pool. 1950392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregorclass ASTDeclContextNameLookupTrait { 195177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor ASTWriter &Writer; 1952392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 195310694cee2588442bee1e717f5042c58ffee25279Douglas Gregorpublic: 195477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor typedef DeclarationName key_type; 195577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor typedef key_type key_type_ref; 195677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 195777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor typedef DeclContext::lookup_result data_type; 195877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor typedef const data_type& data_type_ref; 1959392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 1960392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { } 1961392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 1962392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor unsigned ComputeHash(DeclarationName Name) { 1963392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor llvm::FoldingSetNodeID ID; 1964392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor ID.AddInteger(Name.getNameKind()); 1965392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 1966392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor switch (Name.getNameKind()) { 1967392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::Identifier: 196855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor ID.AddString(Name.getAsIdentifierInfo()->getName()); 196955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor break; 197055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor case DeclarationName::ObjCZeroArgSelector: 197155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor case DeclarationName::ObjCOneArgSelector: 197255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor case DeclarationName::ObjCMultiArgSelector: 197355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector())); 197455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor break; 197555988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor case DeclarationName::CXXConstructorName: 197655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor case DeclarationName::CXXDestructorName: 197755988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor case DeclarationName::CXXConversionFunctionName: 197855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType())); 197955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor break; 1980af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor case DeclarationName::CXXOperatorName: 1981af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor ID.AddInteger(Name.getCXXOverloadedOperator()); 1982af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor break; 1983af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor case DeclarationName::CXXLiteralOperatorName: 1984af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor ID.AddString(Name.getCXXLiteralIdentifier()->getName()); 19850adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor case DeclarationName::CXXUsingDirective: 19860adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor break; 1987af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor } 1988af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor 1989af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor return ID.ComputeHash(); 1990af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor } 1991af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor 1992af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor std::pair<unsigned,unsigned> 1993392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name, 1994392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor data_type_ref Lookup) { 1995392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor unsigned KeyLen = 1; 1996392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor switch (Name.getNameKind()) { 1997392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::Identifier: 19981a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor case DeclarationName::ObjCZeroArgSelector: 1999392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::ObjCOneArgSelector: 2000392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::ObjCMultiArgSelector: 2001392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::CXXConstructorName: 2002392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::CXXDestructorName: 2003392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::CXXConversionFunctionName: 2004392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::CXXLiteralOperatorName: 2005392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor KeyLen += 4; 2006392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor break; 2007392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor case DeclarationName::CXXOperatorName: 2008392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor KeyLen += 1; 2009392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor break; 2010e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor case DeclarationName::CXXUsingDirective: 2011e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor break; 2012e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 2013392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor clang::io::Emit16(Out, KeyLen); 2014392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 2015185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor // 2 bytes for num of decls and 4 for each DeclID. 2016185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first); 2017e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor clang::io::Emit16(Out, DataLen); 2018185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor 201955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor return std::make_pair(KeyLen, DataLen); 202055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor } 2021185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor 202255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) { 202355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor using namespace clang::io; 2024185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor 2025185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor assert(Name.getNameKind() < 0x100 && "Invalid name kind ?"); 2026185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor Emit8(Out, Name.getNameKind()); 2027e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor switch (Name.getNameKind()) { 2028e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor case DeclarationName::Identifier: 2029185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo())); 2030185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor break; 2031e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor case DeclarationName::ObjCZeroArgSelector: 2032185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor case DeclarationName::ObjCOneArgSelector: 2033185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor case DeclarationName::ObjCMultiArgSelector: 2034d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector())); 2035f41d3be39980d40849850d3fb90403623cc8459eArgyrios Kyrtzidis break; 2036d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DeclarationName::CXXConstructorName: 20373efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis case DeclarationName::CXXDestructorName: 20383efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis case DeclarationName::CXXConversionFunctionName: 2039d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie Emit32(Out, Writer.getTypeID(Name.getCXXNameType())); 20403efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis break; 20413efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis case DeclarationName::CXXOperatorName: 20423efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?"); 20433efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis Emit8(Out, Name.getCXXOverloadedOperator()); 2044ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar break; 20453efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis case DeclarationName::CXXLiteralOperatorName: 2046b1c99c679adb53be8f478d08be83af6c9c22ae4bDaniel Dunbar Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier())); 2047b1c99c679adb53be8f478d08be83af6c9c22ae4bDaniel Dunbar break; 2048b1c99c679adb53be8f478d08be83af6c9c22ae4bDaniel Dunbar case DeclarationName::CXXUsingDirective: 20493efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis break; 2050f41d3be39980d40849850d3fb90403623cc8459eArgyrios Kyrtzidis } 20513efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis } 20523efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis 2053f41d3be39980d40849850d3fb90403623cc8459eArgyrios Kyrtzidis void EmitData(llvm::raw_ostream& Out, key_type_ref, 2054f41d3be39980d40849850d3fb90403623cc8459eArgyrios Kyrtzidis data_type Lookup, unsigned DataLen) { 205560f7684881f9f6bc779e91212aea89d9afc723ddArgyrios Kyrtzidis uint64_t Start = Out.tell(); (void)Start; 20563efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis clang::io::Emit16(Out, Lookup.second - Lookup.first); 2057f41d3be39980d40849850d3fb90403623cc8459eArgyrios Kyrtzidis for (; Lookup.first != Lookup.second; ++Lookup.first) 2058f41d3be39980d40849850d3fb90403623cc8459eArgyrios Kyrtzidis clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first)); 2059c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson 2060c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson assert(Out.tell() - Start == DataLen && "Data length is wrong"); 2061c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson } 2062c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson}; 2063c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson} // end anonymous namespace 2064c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson 2065c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson/// \brief Write the block containing all of the declaration IDs 2066c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson/// visible from the given DeclContext. 2067c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson/// 2068c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the 2069c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson/// bitstream, or 0 if no block was written. 2070c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlssonuint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, 2071c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson DeclContext *DC) { 2072c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson if (DC->getPrimaryContext() != DC) 2073c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson return 0; 2074e92b8a1dbba150e213c4980710fcb59ec5c5c570Douglas Gregor 2075c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson // Since there is no name lookup into functions or methods, don't bother to 2076c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson // build a visible-declarations table for these entities. 2077c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson if (DC->isFunctionOrMethod()) 2078c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson return 0; 20796e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer 2080c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson // If not in C++, we perform name lookup for the translation unit via the 2081c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson // IdentifierInfo chains, don't bother to build a visible-declarations table. 20824fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // FIXME: In C++ we need the visible declarations in order to "see" the 20834fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // friend declarations, is there a way to do this without writing the table ? 20844fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) 20850b1fb988012da21d996c43e36867787a7a07b889Chris Lattner return 0; 20863397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 2087a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl // Force the DeclContext to build a its name-lookup table. 208801b81c4d074bba9c18372d521405dfe32fc4f552Argyrios Kyrtzidis if (DC->hasExternalVisibleStorage()) 2089c8e5d51f51e46c6f7717761537c6609ef9daf57cArgyrios Kyrtzidis DC->MaterializeVisibleDeclsFromExternalStorage(); 2090c8e5d51f51e46c6f7717761537c6609ef9daf57cArgyrios Kyrtzidis else 20911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DC->lookup(DeclarationName()); 209297475834207bf5abb5b58534f783c9b71d4b9df1Douglas Gregor 209355f48de5f6b10b50f4d88a9f7235f4532f799550Douglas Gregor // Serialize the contents of the mapping used for lookup. Note that, 20942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // although we have two very different code paths, the serialized 2095c8e5d51f51e46c6f7717761537c6609ef9daf57cArgyrios Kyrtzidis // representation is the same for both cases: a declaration name, 2096681d7237e1014bf64dd5ead6bf74ae55cdd19e61Sebastian Redl // followed by a size, followed by references to the visible 2097c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor // declarations that have that name. 2098681d7237e1014bf64dd5ead6bf74ae55cdd19e61Sebastian Redl uint64_t Offset = Stream.GetCurrentBitNo(); 2099681d7237e1014bf64dd5ead6bf74ae55cdd19e61Sebastian Redl StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); 2100681d7237e1014bf64dd5ead6bf74ae55cdd19e61Sebastian Redl if (!Map || Map->empty()) 21012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return 0; 21022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 21032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; 21041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ASTDeclContextNameLookupTrait Trait(*this); 21052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 21063397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl // Create the on-disk hash table representation. 21070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); 2108a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor D != DEnd; ++D) { 2109a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor DeclarationName Name = D->first; 2110a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor DeclContext::lookup_result Result = D->second.getLookupResult(); 21110953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Generator.insert(Name, Result, Trait); 21128538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl } 21130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 21140953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Create the on-disk hash table in a buffer. 21150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall llvm::SmallString<4096> LookupTable; 21160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall uint32_t BucketOffset; 21172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { 2118b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump llvm::raw_svector_ostream Out(LookupTable); 21192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // Make sure that no bucket is at offset 0 21202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor clang::io::Emit32(Out, 0); 21210953e767ff7817f97b3ab20896b229891eeff45bJohn McCall BucketOffset = Generator.Emit(Out, Trait); 21222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 21232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 21242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // Write the lookup table 2125c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor RecordData Record; 21260b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor Record.push_back(DECL_CONTEXT_VISIBLE); 21270b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor Record.push_back(BucketOffset); 2128c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, 21292cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor LookupTable.str()); 21302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 21314fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); 21324fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor ++NumVisibleDeclContexts; 21334fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor return Offset; 21344fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor} 21352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 21362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// \brief Write an UPDATE_VISIBLE block for the given context. 21372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 21382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing 21392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// DeclContext in a dependent AST file. As such, they only exist for the TU 2140a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl/// (in C++) and for namespaces. 21412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { 214217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis assert((DC->isTranslationUnit() || DC->isNamespace()) && 21432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor "Only TU and namespaces should have visible decl updates."); 21442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2145c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor // Make the context build its lookup table, but don't make it load external 21462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // decls. 21478538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl DC->lookup(DeclarationName()); 21485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner 214917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); 215017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis if (!Map || Map->empty()) 2151eb5e9986e577b1e2bff3cca5973a2494fb593fbbArgyrios Kyrtzidis return; 21522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 21532512308525ff328aa992da0b5ee14a488d2ea93aDouglas Gregor OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; 21546e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer ASTDeclContextNameLookupTrait Trait(*this); 21552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 21562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // Create the hash table. 21572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); 2158a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl D != DEnd; ++D) { 21591476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl DeclarationName Name = D->first; 21601476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl DeclContext::lookup_result Result = D->second.getLookupResult(); 21611476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl // For any name that appears in this table, the results are complete, i.e. 21621476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl // they overwrite results from previous PCHs. Merging is always a mess. 21631476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl Generator.insert(Name, Result, Trait); 21648538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl } 21651476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl 2166a119da0761cb6b85f53857eaee50f6ad8c5ea0a0Douglas Gregor // Create the on-disk hash table in a buffer. 21671476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl llvm::SmallString<4096> LookupTable; 21681476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl uint32_t BucketOffset; 21691476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl { 21708538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl llvm::raw_svector_ostream Out(LookupTable); 21711476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl // Make sure that no bucket is at offset 0 2172a119da0761cb6b85f53857eaee50f6ad8c5ea0a0Douglas Gregor clang::io::Emit32(Out, 0); 21736e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer BucketOffset = Generator.Emit(Out, Trait); 21741476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl } 21751476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl 21761476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl // Write the lookup table 21778538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl RecordData Record; 21781476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl Record.push_back(UPDATE_VISIBLE); 2179496c709a6f08f5c502b6f592ddd9ed40f953a5e5Douglas Gregor Record.push_back(getDeclID(cast<Decl>(DC))); 21801476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl Record.push_back(BucketOffset); 21811476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); 21821476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl} 21838538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 21841476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl//===----------------------------------------------------------------------===// 21850a14e4bf604a91b035a479235adf4c2f6c9128a2Douglas Gregor// General Serialization Routines 21866e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer//===----------------------------------------------------------------------===// 21871476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl 21881476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl/// \brief Write a record containing the given attributes. 218910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) { 219010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis Record.push_back(Attrs.size()); 219110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){ 219210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis const Attr * A = *i; 219310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs 219410f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis AddSourceLocation(A->getLocation(), Record); 219510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis Record.push_back(A->isInherited()); 219610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 219710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis#include "clang/Serialization/AttrPCHWrite.inc" 219810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 219910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis } 220010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis} 220110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 220210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::AddString(llvm::StringRef Str, RecordDataImpl &Record) { 220310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis Record.push_back(Str.size()); 220410f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis Record.insert(Record.end(), Str.begin(), Str.end()); 220510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis} 220610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 220710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis/// \brief Note that the identifier II occurs at the given offset 220810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis/// within the identifier table. 220910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { 221010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis IdentID ID = IdentifierIDs[II]; 221110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // Only store offsets new to this AST file. Other identifier names are looked 22124fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor // up earlier in the chain and thus don't need an offset. 22134fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (ID >= FirstIdentID) 22144fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor IdentifierOffsets[ID - FirstIdentID] = Offset; 22154fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor} 22163251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 2217f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor/// \brief Note that the selector Sel occurs at the given offset 22183397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl/// within the method pool/selector table. 2219a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redlvoid ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { 2220f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor unsigned ID = SelectorIDs[Sel]; 2221f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor assert(ID && "Unknown selector"); 2222f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // Don't record offsets for selectors that are also available in a different 2223f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // file. 22241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ID < FirstSelectorID) 22255d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl return; 22268538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl SelectorOffsets[ID - FirstSelectorID] = Offset; 22275d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl} 22285d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl 2229f0aaf7a59729a4ae0146e3464ee987745be95829Douglas GregorASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) 2230f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor : Stream(Stream), Chain(0), FirstDeclID(1), NextDeclID(FirstDeclID), 22313397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), 22321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), 2233f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID), 22340eca89e9890db4d8336ce762a5b359a1d58ca02bArgyrios Kyrtzidis CollectedStmts(&StmtsToEmit), 2235f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), 22361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump NumVisibleDeclContexts(0) { 22371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 22385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner 2239f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregorvoid ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2240f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor const char *isysroot) { 2241f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // Emit the file header. 22425d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl Stream.Emit((unsigned)'C', 8); 22435d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl Stream.Emit((unsigned)'P', 8); 2244f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Stream.Emit((unsigned)'C', 8); 2245f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Stream.Emit((unsigned)'H', 8); 2246f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 22475d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl WriteBlockInfoBlock(); 2248f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 2249f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor if (Chain) 2250f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor WriteASTChain(SemaRef, StatCalls, isysroot); 2251f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor else 2252f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor WriteASTCore(SemaRef, StatCalls, isysroot); 2253f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor} 22541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 22555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, 22561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const char *isysroot) { 225783941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor using namespace llvm; 225883941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor 2259f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor ASTContext &Context = SemaRef.Context; 2260f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Preprocessor &PP = SemaRef.PP; 2261f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 2262f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // The translation unit is the first declaration we'll emit. 2263f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor DeclIDs[Context.getTranslationUnitDecl()] = 1; 22641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ++NextDeclID; 2265f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor DeclTypesToEmit.push(Context.getTranslationUnitDecl()); 2266f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 22671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Make sure that we emit IdentifierInfos (and any attached 22685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner // declarations) for builtins. 2269a67e58c8fa03c2f1aa7609bf5a436d1adba75eefDouglas Gregor { 2270a67e58c8fa03c2f1aa7609bf5a436d1adba75eefDouglas Gregor IdentifierTable &Table = PP.getIdentifierTable(); 22715d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl llvm::SmallVector<const char *, 32> BuiltinNames; 2272f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Context.BuiltinInfo.GetBuiltinNames(BuiltinNames, 22735d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl Context.getLangOptions().NoBuiltin); 2274f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I) 2275f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor getIdentifierRef(&Table.get(BuiltinNames[I])); 2276f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor } 2277f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 2278f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // Build a record containing all of the tentative definitions in this file, in 22795d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl // TentativeDefinitions order. Generally, this record will be empty for 2280f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // headers. 2281f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor RecordData TentativeDefinitions; 2282f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 2283f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 2284f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor } 2285f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 22865d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl // Build a record containing all of the file scoped decls in this file. 2287f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor RecordData UnusedFileScopedDecls; 2288f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) 2289f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 22905d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl 2291f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor RecordData WeakUndeclaredIdentifiers; 2292f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 2293f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor WeakUndeclaredIdentifiers.push_back( 2294a67e58c8fa03c2f1aa7609bf5a436d1adba75eefDouglas Gregor SemaRef.WeakUndeclaredIdentifiers.size()); 2295a67e58c8fa03c2f1aa7609bf5a436d1adba75eefDouglas Gregor for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 2296f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor I = SemaRef.WeakUndeclaredIdentifiers.begin(), 2297f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 2298f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 2299f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 2300059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 2301f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 2302f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor } 2303059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl } 2304059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl 2305a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl // Build a record containing all of the locally-scoped external 2306f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // declarations in this header file. Generally, this record will be 2307f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // empty. 2308059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl RecordData LocallyScopedExternalDecls; 23095d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl // FIXME: This is filling in the AST file in densemap order which is 2310059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl // nondeterminstic! 2311e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 2312059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl TD = SemaRef.LocallyScopedExternalDecls.begin(), 2313f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 23143397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl TD != TDEnd; ++TD) 23155d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis AddDeclRef(TD->second, LocallyScopedExternalDecls); 23161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2317059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl // Build a record containing all of the ext_vector declarations. 2318059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl RecordData ExtVectorDecls; 2319e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) 23208538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 23215d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl 23225d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl // Build a record containing all of the VTable uses information. 23235d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl RecordData VTableUses; 2324059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl if (!SemaRef.VTableUses.empty()) { 23253397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl VTableUses.push_back(SemaRef.VTableUses.size()); 23265d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 23275d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 23285d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 23295d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 23305d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl } 23315d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl } 23325d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl 23335d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl // Build a record containing all of dynamic classes declarations. 23343397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl RecordData DynamicClasses; 2335e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 2336e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 2337e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl 2338e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl // Build a record containing all of pending implicit instantiations. 2339e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl RecordData PendingInstantiations; 2340e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl for (std::deque<Sema::PendingImplicitInstantiation>::iterator 2341919814def90acecd25a35445862f0c0ff72a9b05Douglas Gregor I = SemaRef.PendingInstantiations.begin(), 2342e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl N = SemaRef.PendingInstantiations.end(); I != N; ++I) { 2343e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl AddDeclRef(I->first, PendingInstantiations); 2344e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl AddSourceLocation(I->second, PendingInstantiations); 2345e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl } 2346919814def90acecd25a35445862f0c0ff72a9b05Douglas Gregor assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 2347e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl "There are local ones at end of translation unit!"); 2348e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl 2349e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl // Build a record containing some declaration references. 2350e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl RecordData SemaDeclRefs; 2351fa78dec572259aca763457b435744f79d822c5d4Sebastian Redl if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 2352fa78dec572259aca763457b435744f79d822c5d4Sebastian Redl AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 2353fa78dec572259aca763457b435744f79d822c5d4Sebastian Redl AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 2354e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl } 23555d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 2356f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // Write the remaining AST contents. 2357f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor RecordData Record; 2358f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Stream.EnterSubblock(AST_BLOCK_ID, 5); 23591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump WriteMetadata(Context, isysroot); 2360f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor WriteLanguageOptions(Context.getLangOptions()); 2361f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor if (StatCalls && !isysroot) 23623397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl WriteStatCache(*StatCalls); 2363f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2364f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // Write the record of special types. 2365a67e58c8fa03c2f1aa7609bf5a436d1adba75eefDouglas Gregor Record.clear(); 2366f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 2367f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getBuiltinVaListType(), Record); 2368f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getObjCIdType(), Record); 2369f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getObjCSelType(), Record); 2370f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getObjCProtoType(), Record); 23718538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl AddTypeRef(Context.getObjCClassType(), Record); 2372f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getRawCFConstantStringType(), Record); 237383941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record); 2374f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getFILEType(), Record); 2375f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getjmp_bufType(), Record); 2376f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getsigjmp_bufType(), Record); 237783941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor AddTypeRef(Context.ObjCIdRedefinitionType, Record); 2378f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.ObjCClassRedefinitionType, Record); 23798538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl AddTypeRef(Context.getRawBlockdescriptorType(), Record); 2380f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record); 2381e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl AddTypeRef(Context.ObjCSelRedefinitionType, Record); 2382ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbar AddTypeRef(Context.getRawNSConstantStringType(), Record); 238383941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor Record.push_back(Context.isInt128Installed()); 238483941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor Stream.EmitRecord(SPECIAL_TYPES, Record); 238583941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor 23868538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl // Keep writing types and declarations until all types and 23877c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor // declarations have been written. 2388b18b1fd33f958264630fbae2602c81275bae8c9aDouglas Gregor Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3); 238983941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor WriteDeclsBlockAbbrevs(); 239083941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor while (!DeclTypesToEmit.empty()) { 239183941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor DeclOrType DOT = DeclTypesToEmit.front(); 239283941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor DeclTypesToEmit.pop(); 239383941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor if (DOT.isType()) 23948538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl WriteType(DOT.getType()); 239583941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor else 2396b18b1fd33f958264630fbae2602c81275bae8c9aDouglas Gregor WriteDecl(Context, DOT.getDecl()); 239783941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor } 23986e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer for (DeclsToRewriteTy::iterator 2399f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor I = DeclsToRewrite.begin(), E = DeclsToRewrite.end(); I != E; ++I) { 2400f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor WriteDecl(Context, const_cast<Decl*>(*I)); 2401f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor } 24023397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl Stream.ExitBlock(); 2403a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl 2404320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian WritePreprocessor(PP); 2405320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian WriteSelectors(SemaRef); 2406320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian WriteReferencedSelectorsPool(SemaRef); 2407725cd9686a0f5bb6c994cb3e43f58b63567c6860Sebastian Redl WriteIdentifierTable(PP); 2408320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian 2409725cd9686a0f5bb6c994cb3e43f58b63567c6860Sebastian Redl WriteTypeDeclOffsets(); 24103397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 2411a68340fd55e177a5849cb3adbf66aedce1f6e91bSebastian Redl // Write the record containing external, unnamed definitions. 2412a68340fd55e177a5849cb3adbf66aedce1f6e91bSebastian Redl if (!ExternalDefinitions.empty()) 2413320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 2414320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian 2415320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian // Write the record containing tentative definitions. 2416320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian if (!TentativeDefinitions.empty()) 2417320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 2418320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian 2419320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian // Write the record containing unused file scoped decls. 2420320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian if (!UnusedFileScopedDecls.empty()) 24218538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 2422320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian 2423320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian // Write the record containing weak undeclared identifiers. 24244fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (!WeakUndeclaredIdentifiers.empty()) 24254fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 24264fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor WeakUndeclaredIdentifiers); 24274fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 2428f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor // Write the record containing locally-scoped external definitions. 24293397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl if (!LocallyScopedExternalDecls.empty()) 2430a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 243137e2684abfe38207fdb90620da062bb18c23f29aDouglas Gregor LocallyScopedExternalDecls); 2432eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 24337143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor // Write the record containing ext_vector type names. 24347143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor if (!ExtVectorDecls.empty()) 2435a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 2436a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor 2437a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor // Write the record containing VTable uses information. 24387143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor if (!VTableUses.empty()) 24397143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Stream.EmitRecord(VTABLE_USES, VTableUses); 24407143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor 24417143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor // Write the record containing dynamic classes declarations. 2442eee242ff426bf79149f221798966e58688383c1eDouglas Gregor if (!DynamicClasses.empty()) 24437143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 24447143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor 24457143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor // Write the record containing pending implicit instantiations. 2446ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor if (!PendingInstantiations.empty()) 2447ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); 2448ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor 2449ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor // Write the record containing declaration references of Sema. 24507143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor if (!SemaDeclRefs.empty()) 24517143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 24527143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor 2453ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor // Some simple statistics 2454aa93a875605536d72a10359a0098396192b7d4ecDouglas Gregor Record.clear(); 24557143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Record.push_back(NumStatements); 2456ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor Record.push_back(NumMacros); 2457a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor Record.push_back(NumLexicalDeclContexts); 2458a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor Record.push_back(NumVisibleDeclContexts); 24593251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor Stream.EmitRecord(STATISTICS, Record); 24607143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Stream.ExitBlock(); 24613251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor} 24621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24638538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, 24643251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor const char *isysroot) { 24651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump using namespace llvm; 2466eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 2467eee242ff426bf79149f221798966e58688383c1eDouglas Gregor ASTContext &Context = SemaRef.Context; 2468eee242ff426bf79149f221798966e58688383c1eDouglas Gregor Preprocessor &PP = SemaRef.PP; 24693251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 24703251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor RecordData Record; 24712596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar Stream.EnterSubblock(AST_BLOCK_ID, 5); 24723251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor WriteMetadata(Context, isysroot); 24731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (StatCalls && !isysroot) 24741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump WriteStatCache(*StatCalls); 2475eee242ff426bf79149f221798966e58688383c1eDouglas Gregor // FIXME: Source manager block should only write new stuff, which could be 2476e013d685c6689ac7ae103ee88acf573422d1ed6aDaniel Dunbar // done by tracking the largest ID in the chain 2477a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2478ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor 24797143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor // The special types are in the chained PCH. 24805998da5c29dae3f654cb65738ff237203e2222c8Douglas Gregor 2481ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor // We don't start with the translation unit, but with its decls that 24821329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor // don't come from the chained PCH. 2483eee242ff426bf79149f221798966e58688383c1eDouglas Gregor const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); 2484eee242ff426bf79149f221798966e58688383c1eDouglas Gregor llvm::SmallVector<KindDeclIDPair, 64> NewGlobalDecls; 2485eee242ff426bf79149f221798966e58688383c1eDouglas Gregor for (DeclContext::decl_iterator I = TU->noload_decls_begin(), 2486a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor E = TU->noload_decls_end(); 24878538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl I != E; ++I) { 2488a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor if ((*I)->getPCHLevel() == 0) 2489668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor NewGlobalDecls.push_back(std::make_pair((*I)->getKind(), GetDeclRef(*I))); 249002fc75169afe785c114e795ec4d24edfb4073c42Douglas Gregor else if ((*I)->isChangedSinceDeserialization()) 249102fc75169afe785c114e795ec4d24edfb4073c42Douglas Gregor (void)GetDeclRef(*I); // Make sure it's written, but don't record it. 249202fc75169afe785c114e795ec4d24edfb4073c42Douglas Gregor } 2493d6595a40fe12e3d5ffe5ce48987b379d547439a4Douglas Gregor // We also need to write a lexical updates block for the TU. 24943251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev(); 24953251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); 24961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 24975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abv); 24983251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor Record.clear(); 24993251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor Record.push_back(TU_UPDATE_LEXICAL); 25003251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, 25013251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor reinterpret_cast<const char*>(NewGlobalDecls.data()), 2502e013d685c6689ac7ae103ee88acf573422d1ed6aDaniel Dunbar NewGlobalDecls.size() * sizeof(KindDeclIDPair)); 25033251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor // And in C++, a visible updates block for the TU. 25041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Context.getLangOptions().CPlusPlus) { 25057143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Abv = new llvm::BitCodeAbbrev(); 25068538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); 2507ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 25087143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); 2509a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 2510a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); 2511a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor WriteDeclContextVisibleUpdate(TU); 25125998da5c29dae3f654cb65738ff237203e2222c8Douglas Gregor } 2513a92193ebd9840e5ce4de1b09e49f1b024c0f5c2fDouglas Gregor 25143251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor // Build a record containing all of the new tentative definitions in this 2515ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor // file, in TentativeDefinitions order. 25165998da5c29dae3f654cb65738ff237203e2222c8Douglas Gregor RecordData TentativeDefinitions; 2517ce835df9301d5bee7fc2c70344e05541f21a5ddaDouglas Gregor for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 2518b0b84385f0cb0ea4036579f5f384f1c19b917c7eDaniel Dunbar if (SemaRef.TentativeDefinitions[i]->getPCHLevel() == 0) 2519b0b84385f0cb0ea4036579f5f384f1c19b917c7eDaniel Dunbar AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 2520646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis } 2521b0b84385f0cb0ea4036579f5f384f1c19b917c7eDaniel Dunbar 25225998da5c29dae3f654cb65738ff237203e2222c8Douglas Gregor // Build a record containing all of the file scoped decls in this file. 25233251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor RecordData UnusedFileScopedDecls; 25241329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) { 25255998da5c29dae3f654cb65738ff237203e2222c8Douglas Gregor if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0) 25261329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 25271329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor } 25281329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor 25291329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor // We write the entire table, overwriting the tables from the chain. 2530668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor RecordData WeakUndeclaredIdentifiers; 2531668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 2532668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor WeakUndeclaredIdentifiers.push_back( 2533eee242ff426bf79149f221798966e58688383c1eDouglas Gregor SemaRef.WeakUndeclaredIdentifiers.size()); 2534eee242ff426bf79149f221798966e58688383c1eDouglas Gregor for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 2535f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl I = SemaRef.WeakUndeclaredIdentifiers.begin(), 2536eee242ff426bf79149f221798966e58688383c1eDouglas Gregor E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 2537eee242ff426bf79149f221798966e58688383c1eDouglas Gregor AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 25385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 2539eee242ff426bf79149f221798966e58688383c1eDouglas Gregor AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 25403251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 2541d8c5abb096a5f6babb3709180fe304be5462bcc1Sebastian Redl } 25423251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor } 25433251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 25443251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor // Build a record containing all of the locally-scoped external 25453251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor // declarations in this header file. Generally, this record will be 25463397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl // empty. 2547afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor RecordData LocallyScopedExternalDecls; 2548afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor // FIXME: This is filling in the AST file in densemap order which is 2549afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor // nondeterminstic! 2550afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 2551eee242ff426bf79149f221798966e58688383c1eDouglas Gregor TD = SemaRef.LocallyScopedExternalDecls.begin(), 2552eee242ff426bf79149f221798966e58688383c1eDouglas Gregor TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 2553eee242ff426bf79149f221798966e58688383c1eDouglas Gregor TD != TDEnd; ++TD) { 2554afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor if (TD->second->getPCHLevel() == 0) 2555afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor AddDeclRef(TD->second, LocallyScopedExternalDecls); 2556afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor } 2557afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor 2558afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor // Build a record containing all of the ext_vector declarations. 25593397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl RecordData ExtVectorDecls; 2560eee242ff426bf79149f221798966e58688383c1eDouglas Gregor for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) { 25611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (SemaRef.ExtVectorDecls[I]->getPCHLevel() == 0) 256292b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 256392b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor } 256492b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor 25653397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl // Build a record containing all of the VTable uses information. 256692b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor // We write everything here, because it's too hard to determine whether 256792b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor // a use is new to this part. 256892b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor RecordData VTableUses; 256992b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor if (!SemaRef.VTableUses.empty()) { 257092b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor VTableUses.push_back(SemaRef.VTableUses.size()); 257192b059ea944adaa3e00bb53d63a09868a4752547Douglas Gregor for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 2572f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 2573f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 2574f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 25758538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl } 2576afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor } 2577afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor 2578afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor // Build a record containing all of dynamic classes declarations. 2579eee242ff426bf79149f221798966e58688383c1eDouglas Gregor RecordData DynamicClasses; 2580eee242ff426bf79149f221798966e58688383c1eDouglas Gregor for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 25817143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0) 25827143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 25833251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 2584afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor // Build a record containing all of pending implicit instantiations. 25853251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor RecordData PendingInstantiations; 25861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (std::deque<Sema::PendingImplicitInstantiation>::iterator 2587668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor I = SemaRef.PendingInstantiations.begin(), 25883251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor N = SemaRef.PendingInstantiations.end(); I != N; ++I) { 2589eee242ff426bf79149f221798966e58688383c1eDouglas Gregor if (I->first->getPCHLevel() == 0) { 25903251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor AddDeclRef(I->first, PendingInstantiations); 2591f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor AddSourceLocation(I->second, PendingInstantiations); 2592a67e58c8fa03c2f1aa7609bf5a436d1adba75eefDouglas Gregor } 2593668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor } 2594afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 2595afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor "There are local ones at end of translation unit!"); 2596afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor 2597afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor // Build a record containing some declaration references. 25988538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl // It's not worth the effort to avoid duplication here. 2599668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor RecordData SemaDeclRefs; 26003251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 2601c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 2602afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 2603afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor } 2604afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor 26058538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3); 2606668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor WriteDeclsBlockAbbrevs(); 2607ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbar while (!DeclTypesToEmit.empty()) { 2608afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor DeclOrType DOT = DeclTypesToEmit.front(); 2609afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor DeclTypesToEmit.pop(); 2610afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor if (DOT.isType()) 26112b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor WriteType(DOT.getType()); 26128538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl else 26132b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor WriteDecl(Context, DOT.getDecl()); 26146ec60e00eeaaed78d98c85ce962d6f328094ca14Douglas Gregor } 26152b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor Stream.ExitBlock(); 26162b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor 26172b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor WritePreprocessor(PP); 26182b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor WriteSelectors(SemaRef); 26198538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl WriteReferencedSelectorsPool(SemaRef); 26202b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor WriteIdentifierTable(PP); 26216ec60e00eeaaed78d98c85ce962d6f328094ca14Douglas Gregor WriteTypeDeclOffsets(); 26222b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor 26236e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer /// Build a record containing first declarations from a chained PCH and the 2624afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor /// most recent declarations in this AST that they point to. 2625afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor RecordData FirstLatestDeclIDs; 26264fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor for (FirstLatestDeclMap::iterator 26275d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis I = FirstLatestDecls.begin(), E = FirstLatestDecls.end(); I != E; ++I) { 26285d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis assert(I->first->getPCHLevel() > I->second->getPCHLevel() && 26295d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis "Expected first & second to be in different PCHs"); 26305d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis AddDeclRef(I->first, FirstLatestDeclIDs); 26315d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis AddDeclRef(I->second, FirstLatestDeclIDs); 26325d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis } 26335d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!FirstLatestDeclIDs.empty()) 26345d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(REDECLS_UPDATE_LATEST, FirstLatestDeclIDs); 26355d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26365d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing external, unnamed definitions. 26375d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!ExternalDefinitions.empty()) 26385d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 26395d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26405d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing tentative definitions. 26415d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!TentativeDefinitions.empty()) 26425d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 26435d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26445d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing unused file scoped decls. 26455d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!UnusedFileScopedDecls.empty()) 26465d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 26475d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26485d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing weak undeclared identifiers. 26495d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!WeakUndeclaredIdentifiers.empty()) 26505d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 26515d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis WeakUndeclaredIdentifiers); 26525d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26535d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing locally-scoped external definitions. 26545d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!LocallyScopedExternalDecls.empty()) 26555d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 26565d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis LocallyScopedExternalDecls); 26575d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26585d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing ext_vector type names. 26595d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!ExtVectorDecls.empty()) 26605d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 26615d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26625d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing VTable uses information. 26635d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!VTableUses.empty()) 26645d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(VTABLE_USES, VTableUses); 26655d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26665d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing dynamic classes declarations. 26675d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!DynamicClasses.empty()) 26685d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 26695d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26705d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the record containing pending implicit instantiations. 26715d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!PendingInstantiations.empty()) 26725d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); 26735d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner // Write the record containing declaration references of Sema. 26755d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (!SemaDeclRefs.empty()) 26765d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 26775d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26785d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis // Write the updates to C++ namespaces. 26795d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis for (llvm::SmallPtrSet<const NamespaceDecl *, 16>::iterator 26805d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis I = UpdatedNamespaces.begin(), 26815d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis E = UpdatedNamespaces.end(); 26825d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis I != E; ++I) 26835d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis WriteDeclContextVisibleUpdate(*I); 26845d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26855d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis WriteDeclUpdatesBlocks(); 26865d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26875d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Record.clear(); 2688e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor Record.push_back(NumStatements); 2689e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor Record.push_back(NumMacros); 2690e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor Record.push_back(NumLexicalDeclContexts); 26915d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Record.push_back(NumVisibleDeclContexts); 26925d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis WriteDeclReplacementsBlock(); 26935d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(STATISTICS, Record); 26945d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.ExitBlock(); 26955d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis} 26965d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 26975d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidisvoid ASTWriter::WriteDeclUpdatesBlocks() { 26985d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (DeclUpdates.empty()) 26995d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis return; 27005d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27015d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis RecordData OffsetsRecord; 27025d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, 3); 27035f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (DeclUpdateMap::iterator 27045d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) { 27055d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis const Decl *D = I->first; 27065d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis UpdateRecord &URec = I->second; 27075d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27085d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (DeclsToRewrite.count(D)) 27095d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis continue; // The decl will be written completely,no need to store updates. 27105d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27115d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis uint64_t Offset = Stream.GetCurrentBitNo(); 27125d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(DECL_UPDATES, URec); 27135d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27145d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis OffsetsRecord.push_back(GetDeclRef(D)); 27155d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis OffsetsRecord.push_back(Offset); 27165d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis } 27175d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.ExitBlock(); 27185d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(DECL_UPDATE_OFFSETS, OffsetsRecord); 27195d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis} 27205d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27215d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidisvoid ASTWriter::WriteDeclReplacementsBlock() { 27225d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis if (ReplacedDecls.empty()) 27235d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis return; 2724e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor 2725e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor RecordData Record; 2726e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor for (llvm::SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator 27275d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) { 27285d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Record.push_back(I->first); 27295d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Record.push_back(I->second); 27305d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis } 27315d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Stream.EmitRecord(DECL_REPLACEMENTS, Record); 27325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner} 27335d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27345d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidisvoid ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) { 27355d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis Record.push_back(Loc.getRawEncoding()); 27365d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis} 27375d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27385d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidisvoid ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) { 27395d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis AddSourceLocation(Range.getBegin(), Record); 27405d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis AddSourceLocation(Range.getEnd(), Record); 27415d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis} 27425d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 27435d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidisvoid ASTWriter::AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record) { 2744074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis Record.push_back(Value.getBitWidth()); 2745074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis const uint64_t *Words = Value.getRawData(); 2746074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis Record.append(Words, Words + Value.getNumWords()); 2747074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 27481d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl 2749074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidisvoid ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record) { 2750074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis Record.push_back(Value.isUnsigned()); 2751074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis AddAPInt(Value, Record); 2752074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 2753074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2754074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidisvoid ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record) { 2755074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis AddAPInt(Value.bitcastToAPInt(), Record); 2756074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 2757074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2758074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidisvoid ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) { 2759074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis Record.push_back(getIdentifierRef(II)); 2760074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 2761074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2762074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios KyrtzidisIdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) { 2763074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis if (II == 0) 2764074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis return 0; 2765074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2766074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis IdentID &ID = IdentifierIDs[II]; 2767c266de97e269c3747ffc2d122fe53185b541cb37Douglas Gregor if (ID == 0) 2768a60786b46eaa4766bb57fb3ca4e0191b3f73e42aArgyrios Kyrtzidis ID = NextIdentID++; 2769074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis return ID; 2770074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 2771074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2772074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios KyrtzidisMacroID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) { 2773074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis if (MD == 0) 2774074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis return 0; 2775074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2776074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis MacroID &ID = MacroDefinitions[MD]; 2777074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis if (ID == 0) 2778074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis ID = NextMacroID++; 2779074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis return ID; 2780074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 2781074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2782074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidisvoid ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) { 2783074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis Record.push_back(getSelectorRef(SelRef)); 2784e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor} 2785e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor 2786074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios KyrtzidisSelectorID ASTWriter::getSelectorRef(Selector Sel) { 2787074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis if (Sel.getAsOpaquePtr() == 0) { 2788074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis return 0; 2789074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis } 2790e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor 2791e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor SelectorID &SID = SelectorIDs[Sel]; 2792e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor if (SID == 0 && Chain) { 2793e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor // This might trigger a ReadSelector callback, which will set the ID for 2794e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor // this selector. 2795e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor Chain->LoadSelector(Sel); 2796e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor } 2797e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor if (SID == 0) { 2798e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor SID = NextSelectorID++; 2799e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor } 2800e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor return SID; 2801e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor} 2802e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor 280345118d8f2b50a37472dd03cd1d5b4abd7ae9f25bArgyrios Kyrtzidisvoid ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record) { 2804e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor AddDeclRef(Temp->getDestructor(), Record); 2805074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 2806074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2807e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregorvoid ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, 2808e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor const TemplateArgumentLocInfo &Arg, 2809e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor RecordDataImpl &Record) { 2810e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor switch (Kind) { 2811e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor case TemplateArgument::Expression: 2812e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor AddStmt(Arg.getAsExpr()); 2813e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor break; 2814e5a54b600f74dcb6cca27543df2757115711d80aDouglas Gregor case TemplateArgument::Type: 2815074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record); 2816074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis break; 2817074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis case TemplateArgument::Template: 2818074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis AddSourceRange(Arg.getTemplateQualifierRange(), Record); 2819074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis AddSourceLocation(Arg.getTemplateNameLoc(), Record); 2820074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis break; 2821074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis case TemplateArgument::Null: 2822074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis case TemplateArgument::Integral: 2823074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis case TemplateArgument::Declaration: 2824074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis case TemplateArgument::Pack: 2825074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis break; 2826074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis } 2827074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis} 2828074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2829074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidisvoid ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, 2830074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis RecordDataImpl &Record) { 2831074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis AddTemplateArgument(Arg.getArgument(), Record); 2832074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis 2833074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis if (Arg.getArgument().getKind() == TemplateArgument::Expression) { 2834074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis bool InfoHasSameExpr 2835074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr(); 2836074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis Record.push_back(InfoHasSameExpr); 28371d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl if (InfoHasSameExpr) 28381d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl return; // Avoid storing the same expr twice. 28391d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl } 28401d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(), 28411d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl Record); 28421d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl} 28431d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl 28441d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redlvoid ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record) { 28451d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl if (TInfo == 0) { 28461d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl AddTypeRef(QualType(), Record); 28471d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl return; 28481d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl } 28491d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl 28501d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl AddTypeRef(TInfo->getType(), Record); 28511d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl TypeLocWriter TLW(*this, Record); 28521d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) 28531d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl TLW.Visit(TL); 28541d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl} 28555967d6228f183a5fa384f2f1918df679ed2d8666Sebastian Redl 28565967d6228f183a5fa384f2f1918df679ed2d8666Sebastian Redlvoid ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) { 285745118d8f2b50a37472dd03cd1d5b4abd7ae9f25bArgyrios Kyrtzidis Record.push_back(GetOrCreateTypeID(T)); 285845118d8f2b50a37472dd03cd1d5b4abd7ae9f25bArgyrios Kyrtzidis} 28591d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl 28601d1e42b17da6a53391d50b08068ecde04311e368Sebastian RedlTypeID ASTWriter::GetOrCreateTypeID(QualType T) { 28611d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl return MakeTypeID(T, 28621d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this)); 28631d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl} 28641d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl 28651d1e42b17da6a53391d50b08068ecde04311e368Sebastian RedlTypeID ASTWriter::getTypeID(QualType T) const { 28661d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl return MakeTypeID(T, 28671d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this)); 28681d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl} 28691d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl 28701d1e42b17da6a53391d50b08068ecde04311e368Sebastian RedlTypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) { 28711d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl if (T.isNull()) 28721d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl return TypeIdx(); 28731d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl assert(!T.getLocalFastQualifiers()); 28741d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl 28751d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl TypeIdx &Idx = TypeIdxs[T]; 28761d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl if (Idx.getIndex() == 0) { 28771d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl // We haven't seen this type before. Assign it a new ID and put it 28781d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl // into the queue of types to emit. 287984bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne Idx = TypeIdx(NextTypeID++); 288084bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne DeclTypesToEmit.push(T); 288184bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne } 288284bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne return Idx; 288384bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne} 288484bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne 288584bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter CollingbourneTypeIdx ASTWriter::getTypeIdx(QualType T) const { 288684bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne if (T.isNull()) 288784bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne return TypeIdx(); 288884bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne assert(!T.getLocalFastQualifiers()); 288984bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne 289084bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne TypeIdxMap::const_iterator I = TypeIdxs.find(T); 289184bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne assert(I != TypeIdxs.end() && "Type not emitted!"); 289284bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne return I->second; 289384bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne} 289484bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne 289584bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbournevoid ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { 289684bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne Record.push_back(GetDeclRef(D)); 289784bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne} 28985d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis 28994fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas GregorDeclID ASTWriter::GetDeclRef(const Decl *D) { 29004fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor if (D == 0) { 29014fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor return 0; 290268a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor } 290389eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer"); 29044eb9fc0449ddbd5239ddc3ae6b6e52880f47dcf7Argyrios Kyrtzidis DeclID &ID = DeclIDs[D]; 2905cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (ID == 0) { 2906cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // We haven't seen this declaration before. Give it a new ID and 2907cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // enqueue it in the list of declarations to emit. 2908768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ID = NextDeclID++; 290968a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor DeclTypesToEmit.push(const_cast<Decl *>(D)); 2910cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt } else if (ID < FirstDeclID && D->isChangedSinceDeserialization()) { 29115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // We don't add it to the replacement collection here, because we don't 291268a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor // have the offset yet. 291368a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor DeclTypesToEmit.push(const_cast<Decl *>(D)); 291468a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor // Reset the flag, so that we don't add this decl multiple times. 29155f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner const_cast<Decl *>(D)->setChangedSinceDeserialization(false); 291668a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor } 291768a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor 291868a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor return ID; 291968a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor} 29200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 29210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas GregorDeclID ASTWriter::getDeclID(const Decl *D) { 29220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D == 0) 29230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return 0; 29240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 29250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!"); 29260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return DeclIDs[D]; 29270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 29280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 29290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorvoid ASTWriter::AddDeclarationName(DeclarationName Name, RecordDataImpl &Record) { 29300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc. 29310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Record.push_back(Name.getNameKind()); 29320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor switch (Name.getNameKind()) { 29333251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor case DeclarationName::Identifier: 29343251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor AddIdentifierRef(Name.getAsIdentifierInfo(), Record); 2935a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl break; 29368538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 29373397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl case DeclarationName::ObjCZeroArgSelector: 2938f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl case DeclarationName::ObjCOneArgSelector: 2939f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl case DeclarationName::ObjCMultiArgSelector: 2940f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl AddSelectorRef(Name.getObjCSelector(), Record); 29413251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor break; 29423251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 294383941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor case DeclarationName::CXXConstructorName: 294483941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor case DeclarationName::CXXDestructorName: 2945a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl case DeclarationName::CXXConversionFunctionName: 294683941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor AddTypeRef(Name.getCXXNameType(), Record); 294783941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor break; 2948e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl 2949e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl case DeclarationName::CXXOperatorName: 2950e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl Record.push_back(Name.getCXXOverloadedOperator()); 2951e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl break; 2952e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl 295383941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor case DeclarationName::CXXLiteralOperatorName: 295483941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record); 2955a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl break; 2956e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 2957e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor case DeclarationName::CXXUsingDirective: 29580a14e4bf604a91b035a479235adf4c2f6c9128a2Douglas Gregor // No extra data to emit 29598538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl break; 29606ec60e00eeaaed78d98c85ce962d6f328094ca14Douglas Gregor } 296126ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor} 296226ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor 2963b18b1fd33f958264630fbae2602c81275bae8c9aDouglas Gregorvoid ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, 296477424bc3794f569816dba52e423b57486a98e5baDouglas Gregor DeclarationName Name, RecordDataImpl &Record) { 2965e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl switch (Name.getNameKind()) { 2966a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor case DeclarationName::CXXConstructorName: 2967e92b8a1dbba150e213c4980710fcb59ec5c5c570Douglas Gregor case DeclarationName::CXXDestructorName: 2968953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner case DeclarationName::CXXConversionFunctionName: 2969a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor AddTypeSourceInfo(DNLoc.NamedType.TInfo, Record); 2970a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor break; 2971a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor 2972953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner case DeclarationName::CXXOperatorName: 2973953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner AddSourceLocation( 2974953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.BeginOpNameLoc), 29757c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor Record); 297630c514c225342844700ed4640ec6d90ddf0e12b2Sebastian Redl AddSourceLocation( 29772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc), 297810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis Record); 297910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis break; 298010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 298110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis case DeclarationName::CXXLiteralOperatorName: 298210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis AddSourceLocation( 298310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis SourceLocation::getFromRawEncoding(DNLoc.CXXLiteralOperatorName.OpNameLoc), 2984a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl Record); 29858e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis break; 29861a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor 298761c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor case DeclarationName::Identifier: 298861c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor case DeclarationName::ObjCZeroArgSelector: 29892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor case DeclarationName::ObjCOneArgSelector: 2990c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor case DeclarationName::ObjCMultiArgSelector: 2991c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor case DeclarationName::CXXUsingDirective: 2992c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor break; 2993c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor } 29941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 2995b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner 29962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo, 29973b8043b49aff6e5d70f29ef5684214ce2473763cDouglas Gregor RecordDataImpl &Record) { 2998185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor AddDeclarationName(NameInfo.getName(), Record); 2999e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor AddSourceLocation(NameInfo.getLoc(), Record); 3000a8cc6ce36e70e2afa22ab6b4340035cb3941c2ebDouglas Gregor AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName(), Record); 30013b8043b49aff6e5d70f29ef5684214ce2473763cDouglas Gregor} 3002185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor 3003e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregorvoid ASTWriter::AddQualifierInfo(const QualifierInfo &Info, 300461c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor RecordDataImpl &Record) { 300561c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor AddNestedNameSpecifier(Info.NNS, Record); 30061dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl AddSourceRange(Info.NNSRange, Record); 30071dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl Record.push_back(Info.NumTemplParamLists); 3008a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i) 3009a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor AddTemplateParameterList(Info.TemplParamLists[i], Record); 3010a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor} 3011a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor 3012a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregorvoid ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, 3013a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor RecordDataImpl &Record) { 3014a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor // Nested name specifiers usually aren't too long. I think that 8 would 3015a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor // typically accomodate the vast majority. 3016a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames; 3017a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl 3018832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor // Push each of the NNS's onto a stack for serialization in reverse order. 3019a8cc6ce36e70e2afa22ab6b4340035cb3941c2ebDouglas Gregor while (NNS) { 30201a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor NestedNames.push_back(NNS); 30211dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl NNS = NNS->getPrefix(); 30221dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl } 3023ecc2c090e7146c029dd9ee9a5a2fd66b275c01c0Douglas Gregor 3024ecc2c090e7146c029dd9ee9a5a2fd66b275c01c0Douglas Gregor Record.push_back(NestedNames.size()); 3025ecc2c090e7146c029dd9ee9a5a2fd66b275c01c0Douglas Gregor while(!NestedNames.empty()) { 3026ecc2c090e7146c029dd9ee9a5a2fd66b275c01c0Douglas Gregor NNS = NestedNames.pop_back_val(); 30271dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); 30281dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl Record.push_back(Kind); 30291dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl switch (Kind) { 30306bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor case NestedNameSpecifier::Identifier: 30316bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor AddIdentifierRef(NNS->getAsIdentifier(), Record); 30324dfd02a17c6d604c72e6936527c5e1c56d3ecb7aDouglas Gregor break; 30334dfd02a17c6d604c72e6936527c5e1c56d3ecb7aDouglas Gregor 30347a27ea52b7bd635c89bec5a9c521a3bf7d204238Douglas Gregor case NestedNameSpecifier::Namespace: 30357a27ea52b7bd635c89bec5a9c521a3bf7d204238Douglas Gregor AddDeclRef(NNS->getAsNamespace(), Record); 303679d6726921897811232554ed94c5d77b5b7b3fc0Douglas Gregor break; 303779d6726921897811232554ed94c5d77b5b7b3fc0Douglas Gregor 3038772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor case NestedNameSpecifier::TypeSpec: 3039772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate: 3040772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor AddTypeRef(QualType(NNS->getAsType(), 0), Record); 3041772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); 3042e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor break; 3043e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor 304479d6726921897811232554ed94c5d77b5b7b3fc0Douglas Gregor case NestedNameSpecifier::Global: 3045b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor // Don't need to write an associated value. 3046b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor break; 3047b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor } 3048b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor } 3049b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor} 3050b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor 30512deaea37a637dd01221d0cced343702a39d8132cDouglas Gregorvoid ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) { 30525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner TemplateName::NameKind Kind = Name.getKind(); 30532deaea37a637dd01221d0cced343702a39d8132cDouglas Gregor Record.push_back(Kind); 30542deaea37a637dd01221d0cced343702a39d8132cDouglas Gregor switch (Kind) { 30552deaea37a637dd01221d0cced343702a39d8132cDouglas Gregor case TemplateName::Template: 30562deaea37a637dd01221d0cced343702a39d8132cDouglas Gregor AddDeclRef(Name.getAsTemplateDecl(), Record); 30572deaea37a637dd01221d0cced343702a39d8132cDouglas Gregor break; 30582deaea37a637dd01221d0cced343702a39d8132cDouglas Gregor 3059eee242ff426bf79149f221798966e58688383c1eDouglas Gregor case TemplateName::OverloadedTemplate: { 3060eee242ff426bf79149f221798966e58688383c1eDouglas Gregor OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate(); 3061eee242ff426bf79149f221798966e58688383c1eDouglas Gregor Record.push_back(OvT->size()); 3062eee242ff426bf79149f221798966e58688383c1eDouglas Gregor for (OverloadedTemplateStorage::iterator I = OvT->begin(), E = OvT->end(); 3063eee242ff426bf79149f221798966e58688383c1eDouglas Gregor I != E; ++I) 3064eee242ff426bf79149f221798966e58688383c1eDouglas Gregor AddDeclRef(*I, Record); 3065eee242ff426bf79149f221798966e58688383c1eDouglas Gregor break; 3066eee242ff426bf79149f221798966e58688383c1eDouglas Gregor } 3067eee242ff426bf79149f221798966e58688383c1eDouglas Gregor 306863d65f873fdfcb04b216ea9c648d1df5992aed1cChris Lattner case TemplateName::QualifiedTemplate: { 3069e9d12b6c50c1e9b05443db099e21026c5991a93bSebastian Redl QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); 307063d65f873fdfcb04b216ea9c648d1df5992aed1cChris Lattner AddNestedNameSpecifier(QualT->getQualifier(), Record); 30714c0e86b392c5fb0cb771551fc877edb6979be69cDouglas Gregor Record.push_back(QualT->hasTemplateKeyword()); 3072a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor AddDeclRef(QualT->getTemplateDecl(), Record); 3073a862320972e63349524dc9aa744dec1b95f54ba1Douglas Gregor break; 307449b96d1a382ae9f31456166f1a734d3f7f30b992Argyrios Kyrtzidis } 307549b96d1a382ae9f31456166f1a734d3f7f30b992Argyrios Kyrtzidis 3076a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor case TemplateName::DependentTemplate: { 3077a2ee20aa9660851080135219cac5b31fbac08b78Douglas Gregor DependentTemplateName *DepT = Name.getAsDependentTemplateName(); 30784056680e3c154ef84874410eba55323f9b07aad6Sebastian Redl AddNestedNameSpecifier(DepT->getQualifier(), Record); 3079b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(DepT->isIdentifier()); 3080b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor if (DepT->isIdentifier()) 3081ebcbe1d3dc7d4f0c1f540a632fa0684dd0a857d5Sean Hunt AddIdentifierRef(DepT->getIdentifier(), Record); 30820129b561a1452bf057f6b18b6a1de815d487ab81Douglas Gregor else 3083ebcbe1d3dc7d4f0c1f540a632fa0684dd0a857d5Sean Hunt Record.push_back(DepT->getOperator()); 3084b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor break; 3085b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor } 3086b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor } 308772b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis} 308872b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis 308931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregorvoid ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, 309072b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis RecordDataImpl &Record) { 309172b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis Record.push_back(Arg.getKind()); 309272b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis switch (Arg.getKind()) { 309372b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis case TemplateArgument::Null: 309472b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis break; 309572b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis case TemplateArgument::Type: 309672b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis AddTypeRef(Arg.getAsType(), Record); 309772b90571b1783b17c3f2204cec5ca440edc38beeArgyrios Kyrtzidis break; 309811a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam case TemplateArgument::Declaration: 309914c22f20c077cecd68581952a0c227f8c180be03Douglas Gregor AddDeclRef(Arg.getAsDecl(), Record); 310014c22f20c077cecd68581952a0c227f8c180be03Douglas Gregor break; 310114c22f20c077cecd68581952a0c227f8c180be03Douglas Gregor case TemplateArgument::Integral: 310214c22f20c077cecd68581952a0c227f8c180be03Douglas Gregor AddAPSInt(*Arg.getAsIntegral(), Record); 31033397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl AddTypeRef(Arg.getIntegralType(), Record); 310463d65f873fdfcb04b216ea9c648d1df5992aed1cChris Lattner break; 31051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case TemplateArgument::Template: 310614c22f20c077cecd68581952a0c227f8c180be03Douglas Gregor AddTemplateName(Arg.getAsTemplate(), Record); 310714c22f20c077cecd68581952a0c227f8c180be03Douglas Gregor break; 3108ec12ce2f6da44bfc9048772327a3924498099d60Douglas Gregor case TemplateArgument::Expression: 3109919814def90acecd25a35445862f0c0ff72a9b05Douglas Gregor AddStmt(Arg.getAsExpr()); 3110ec12ce2f6da44bfc9048772327a3924498099d60Douglas Gregor break; 3111ec12ce2f6da44bfc9048772327a3924498099d60Douglas Gregor case TemplateArgument::Pack: 3112ec12ce2f6da44bfc9048772327a3924498099d60Douglas Gregor Record.push_back(Arg.pack_size()); 3113b81c17092039f39be60e9656a37cffbdf2e2c783Douglas Gregor for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end(); 3114b81c17092039f39be60e9656a37cffbdf2e2c783Douglas Gregor I != E; ++I) 3115d58a0a55e64a7c410a80e9d6dcd899e61e99cc4dDouglas Gregor AddTemplateArgument(*I, Record); 3116b81c17092039f39be60e9656a37cffbdf2e2c783Douglas Gregor break; 3117d455add086f1dfa16ae87dc310e49493bbc2b0a6Argyrios Kyrtzidis } 3118d455add086f1dfa16ae87dc310e49493bbc2b0a6Argyrios Kyrtzidis} 3119be4ebcdaa03a84d915b37f96d241b74eece67c92Argyrios Kyrtzidis 3120be4ebcdaa03a84d915b37f96d241b74eece67c92Argyrios Kyrtzidisvoid 3121be4ebcdaa03a84d915b37f96d241b74eece67c92Argyrios KyrtzidisASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams, 3122be4ebcdaa03a84d915b37f96d241b74eece67c92Argyrios Kyrtzidis RecordDataImpl &Record) { 3123be4ebcdaa03a84d915b37f96d241b74eece67c92Argyrios Kyrtzidis assert(TemplateParams && "No TemplateParams!"); 3124be4ebcdaa03a84d915b37f96d241b74eece67c92Argyrios Kyrtzidis AddSourceLocation(TemplateParams->getTemplateLoc(), Record); 3125d455add086f1dfa16ae87dc310e49493bbc2b0a6Argyrios Kyrtzidis AddSourceLocation(TemplateParams->getLAngleLoc(), Record); 3126d455add086f1dfa16ae87dc310e49493bbc2b0a6Argyrios Kyrtzidis AddSourceLocation(TemplateParams->getRAngleLoc(), Record); 3127d455add086f1dfa16ae87dc310e49493bbc2b0a6Argyrios Kyrtzidis Record.push_back(TemplateParams->size()); 3128d455add086f1dfa16ae87dc310e49493bbc2b0a6Argyrios Kyrtzidis for (TemplateParameterList::const_iterator 3129a126f17ca83b985300c1f65cee647bea108db657Douglas Gregor P = TemplateParams->begin(), PEnd = TemplateParams->end(); 3130d455add086f1dfa16ae87dc310e49493bbc2b0a6Argyrios Kyrtzidis P != PEnd; ++P) 31310e0363866792b309d70e9c8e92b4c239773af89cArgyrios Kyrtzidis AddDeclRef(*P, Record); 313262c78d54bee499dd87f768f48b21c9b5ec15e516Chandler Carruth} 31330e0363866792b309d70e9c8e92b4c239773af89cArgyrios Kyrtzidis 313462c78d54bee499dd87f768f48b21c9b5ec15e516Chandler Carruth/// \brief Emit a template argument list. 313562c78d54bee499dd87f768f48b21c9b5ec15e516Chandler Carruthvoid 313662c78d54bee499dd87f768f48b21c9b5ec15e516Chandler CarruthASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, 313762c78d54bee499dd87f768f48b21c9b5ec15e516Chandler Carruth RecordDataImpl &Record) { 31380e0363866792b309d70e9c8e92b4c239773af89cArgyrios Kyrtzidis assert(TemplateArgs && "No TemplateArgs!"); 31390e0363866792b309d70e9c8e92b4c239773af89cArgyrios Kyrtzidis Record.push_back(TemplateArgs->flat_size()); 31400e0363866792b309d70e9c8e92b4c239773af89cArgyrios Kyrtzidis for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i) 31410e0363866792b309d70e9c8e92b4c239773af89cArgyrios Kyrtzidis AddTemplateArgument(TemplateArgs->get(i), Record); 314276c38d385447b7acdff2d7e6b13fa8580e7174a7Argyrios Kyrtzidis} 314376c38d385447b7acdff2d7e6b13fa8580e7174a7Argyrios Kyrtzidis 314476c38d385447b7acdff2d7e6b13fa8580e7174a7Argyrios Kyrtzidis 314576c38d385447b7acdff2d7e6b13fa8580e7174a7Argyrios Kyrtzidisvoid 314676c38d385447b7acdff2d7e6b13fa8580e7174a7Argyrios KyrtzidisASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record) { 314776c38d385447b7acdff2d7e6b13fa8580e7174a7Argyrios Kyrtzidis Record.push_back(Set.size()); 314876c38d385447b7acdff2d7e6b13fa8580e7174a7Argyrios Kyrtzidis for (UnresolvedSetImpl::const_iterator 314914b6ba77710d6431794d65c7d58c6f29c3dc956ePeter Collingbourne I = Set.begin(), E = Set.end(); I != E; ++I) { 315014b6ba77710d6431794d65c7d58c6f29c3dc956ePeter Collingbourne AddDeclRef(I.getDecl(), Record); 315114b6ba77710d6431794d65c7d58c6f29c3dc956ePeter Collingbourne Record.push_back(I.getAccess()); 315214b6ba77710d6431794d65c7d58c6f29c3dc956ePeter Collingbourne } 315314b6ba77710d6431794d65c7d58c6f29c3dc956ePeter Collingbourne} 3154d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor 3155d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregorvoid ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, 3156d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor RecordDataImpl &Record) { 3157d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor Record.push_back(Base.isVirtual()); 3158d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor Record.push_back(Base.isBaseOfClass()); 3159d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor Record.push_back(Base.getAccessSpecifierAsWritten()); 3160d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor AddTypeSourceInfo(Base.getTypeSourceInfo(), Record); 3161d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor AddSourceRange(Base.getSourceRange(), Record); 3162d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor} 3163d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor 31643397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTWriter::AddCXXBaseOrMemberInitializers( 3165ad1de006ea080b540e480efc6b86c2e201dbf1ecDouglas Gregor const CXXBaseOrMemberInitializer * const *BaseOrMembers, 31668538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl unsigned NumBaseOrMembers, RecordDataImpl &Record) { 31678e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis Record.push_back(NumBaseOrMembers); 31681dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl for (unsigned i=0; i != NumBaseOrMembers; ++i) { 3169832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor const CXXBaseOrMemberInitializer *Init = BaseOrMembers[i]; 3170dd41ed59cf7aefabd40bf766d8fcc7ebd759c8e5Douglas Gregor 31711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Record.push_back(Init->isBaseInitializer()); 3172b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor if (Init->isBaseInitializer()) { 3173b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor AddTypeSourceInfo(Init->getBaseClassInfo(), Record); 31746bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Init->isBaseVirtual()); 31756bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor } else { 31766bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor AddDeclRef(Init->getMember(), Record); 3177b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor } 31786bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor AddSourceLocation(Init->getMemberLocation(), Record); 3179919814def90acecd25a35445862f0c0ff72a9b05Douglas Gregor AddStmt(Init->getInit()); 31806bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor AddDeclRef(Init->getAnonUnionMember(), Record); 31816bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor AddSourceLocation(Init->getLParenLoc(), Record); 3182b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor AddSourceLocation(Init->getRParenLoc(), Record); 31836bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Init->isWritten()); 31846bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor if (Init->isWritten()) { 31856bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Init->getSourceOrder()); 31866bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor } else { 31876bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Init->getNumArrayIndices()); 31886bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i) 31896bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor AddDeclRef(Init->getArrayIndex(i), Record); 31906bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor } 31916bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor } 3192b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor} 31936bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor 31946bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregorvoid ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) { 31956bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor assert(D->DefinitionData); 31966bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; 31976bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.UserDeclaredConstructor); 31986bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.UserDeclaredCopyConstructor); 31996bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.UserDeclaredCopyAssignment); 32006bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.UserDeclaredDestructor); 3201b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.Aggregate); 3202b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.PlainOldData); 32036bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.Empty); 32046bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.Polymorphic); 3205b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.Abstract); 3206b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.HasTrivialConstructor); 320761c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor Record.push_back(Data.HasTrivialCopyConstructor); 3208b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.HasTrivialCopyAssignment); 32096bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.HasTrivialDestructor); 32106bf2b9fbd3e3adc38d4712de79aeaa81d651aa08Douglas Gregor Record.push_back(Data.ComputedVisibleConversions); 321167bc4ba9894506c461aeff11302c2d2471b82273Argyrios Kyrtzidis Record.push_back(Data.DeclaredDefaultConstructor); 321261c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor Record.push_back(Data.DeclaredCopyConstructor); 321361c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor Record.push_back(Data.DeclaredCopyAssignment); 3214b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.DeclaredDestructor); 3215b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor 3216b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.NumBases); 3217b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor for (unsigned i = 0; i != Data.NumBases; ++i) 3218b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor AddCXXBaseSpecifier(Data.Bases[i], Record); 3219b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor 3220b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor // FIXME: Make VBases lazily computed when needed to avoid storing them. 3221b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor Record.push_back(Data.NumVBases); 3222b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor for (unsigned i = 0; i != Data.NumVBases; ++i) 3223b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor AddCXXBaseSpecifier(Data.VBases[i], Record); 3224b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor 3225e2d4f4ed44a32f179c6d48cd1dba8346ab2129d9Rafael Espindola AddUnresolvedSet(Data.Conversions, Record); 3226185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor AddUnresolvedSet(Data.VisibleConversions, Record); 3227366809a4e9340b3458b471e2294a75a9f09ea304Douglas Gregor // Data.Definition is the owning decl, no need to write it. 3228366809a4e9340b3458b471e2294a75a9f09ea304Douglas Gregor AddDeclRef(Data.FirstFriend, Record); 3229a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor} 323061d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor 3231b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregorvoid ASTWriter::ReaderInitialized(ASTReader *Reader) { 3232b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor assert(Reader && "Cannot remove chain"); 3233b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor assert(!Chain && "Cannot replace chain"); 3234b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor assert(FirstDeclID == NextDeclID && 323561d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor FirstTypeID == NextTypeID && 323661d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor FirstIdentID == NextIdentID && 323761d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor FirstSelectorID == NextSelectorID && 323861d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor FirstMacroID == NextMacroID && 323961d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor "Setting chain after writing has started."); 324061d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor Chain = Reader; 324161d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor 324261d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor FirstDeclID += Chain->getTotalNumDecls(); 324361d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor FirstTypeID += Chain->getTotalNumTypes(); 324411a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam FirstIdentID += Chain->getTotalNumIdentifiers(); 324510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis FirstSelectorID += Chain->getTotalNumSelectors(); 324610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis FirstMacroID += Chain->getTotalNumMacroDefinitions(); 324710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis NextDeclID = FirstDeclID; 324810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis NextTypeID = FirstTypeID; 324910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis NextIdentID = FirstIdentID; 325010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis NextSelectorID = FirstSelectorID; 325110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis NextMacroID = FirstMacroID; 325210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis} 325310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 325410f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) { 325510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis IdentifierIDs[II] = ID; 325610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis} 325710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 325826ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregorvoid ASTWriter::TypeRead(TypeIdx Idx, QualType T) { 325910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // Always take the highest-numbered type index. This copes with an interesting 326010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // case for chained AST writing where we schedule writing the type and then, 326110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // later, deserialize the type from another AST. In this case, we want to 326210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // keep the higher-numbered entry so that we can properly write it out to 326310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // the AST file. 326410f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis TypeIdx &StoredIdx = TypeIdxs[T]; 326510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis if (Idx.getIndex() >= StoredIdx.getIndex()) 326610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis StoredIdx = Idx; 326710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis} 326810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 326910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::DeclRead(DeclID ID, const Decl *D) { 327010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis DeclIDs[D] = ID; 327110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis} 3272af13bfc3b40aa4a46f4e71d200ecfb10f45297fcDouglas Gregor 327310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::SelectorRead(SelectorID ID, Selector S) { 327410f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis SelectorIDs[S] = ID; 327510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis} 327610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 327710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::MacroDefinitionRead(serialization::MacroID ID, 327810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis MacroDefinition *MD) { 327910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis MacroDefinitions[MD] = ID; 328026ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor} 328110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis 328210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisvoid ASTWriter::CompletedTagDefinition(const TagDecl *D) { 328310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis assert(D->isDefinition()); 328410f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 328510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // We are interested when a PCH decl is modified. 328610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis if (RD->getPCHLevel() > 0) { 328710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // A forward reference was mutated into a definition. Rewrite it. 328810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // FIXME: This happens during template instantiation, should we 328910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis // have created a new definition decl instead ? 329010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis DeclsToRewrite.insert(RD); 3291a8cc6ce36e70e2afa22ab6b4340035cb3941c2ebDouglas Gregor } 3292cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 3293059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl for (CXXRecordDecl::redecl_iterator 3294320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian I = RD->redecls_begin(), E = RD->redecls_end(); I != E; ++I) { 3295a8cc6ce36e70e2afa22ab6b4340035cb3941c2ebDouglas Gregor CXXRecordDecl *Redecl = cast<CXXRecordDecl>(*I); 329684bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne if (Redecl == RD) 329784bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne continue; 32988f5dc7fe4d42cea78fa92d1638f753cf65b54cb5Douglas Gregor 32991476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl // We are interested when a PCH decl is modified. 33003efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis if (Redecl->getPCHLevel() > 0) { 3301ad1de006ea080b540e480efc6b86c2e201dbf1ecDouglas Gregor UpdateRecord &Record = DeclUpdates[Redecl]; 3302c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson Record.push_back(UPD_CXX_SET_DEFINITIONDATA); 33037c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor assert(Redecl->DefinitionData); 3304e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor assert(Redecl->DefinitionData->Definition == D); 3305e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor AddDeclRef(D, Record); // the DefinitionDecl 3306e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 3307e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 3308a119da0761cb6b85f53857eaee50f6ad8c5ea0a0Douglas Gregor } 3309a119da0761cb6b85f53857eaee50f6ad8c5ea0a0Douglas Gregor} 3310a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis 33113397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { 3312a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis assert(D->isImplicit()); 3313b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor if (!(D->getPCHLevel() == 0 && RD->getPCHLevel() > 0)) 3314b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor return; // Not a source member added to a class from PCH. 3315b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor if (!isa<CXXMethodDecl>(D)) 3316a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis return; // We are interested in lazily declared implicit methods. 3317a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis 3318a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis // A decl coming from PCH was modified. 3319b7c324f8581a55e2a918e5f3eb2e7418b09df0f2Douglas Gregor assert(RD->isDefinition()); 3320a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis UpdateRecord &Record = DeclUpdates[RD]; 33218538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER); 3322a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis AddDeclRef(D, Record); 3323083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl} 3324083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl 33258538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, 3326083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl const ClassTemplateSpecializationDecl *D) { 3327083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0)) 3328083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl return; // Not a source specialization added to a template from PCH. 33298538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 3330083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl UpdateRecord &Record = DeclUpdates[TD]; 333149b96d1a382ae9f31456166f1a734d3f7f30b992Argyrios Kyrtzidis Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); 333249b96d1a382ae9f31456166f1a734d3f7f30b992Argyrios Kyrtzidis AddDeclRef(D, Record); 33338538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 3334083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl