ASTWriter.cpp revision 074dcc8ef8c5df7a155c85648e8eae786bee6cab
150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//===--- ASTWriter.cpp - AST File Writer ----------------------------------===// 250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// The LLVM Compiler Infrastructure 4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// This file is distributed under the University of Illinois Open Source 650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// License. See LICENSE.TXT for details. 750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//===----------------------------------------------------------------------===// 950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// This file defines the ASTWriter class, which writes AST files. 1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//===----------------------------------------------------------------------===// 1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "clang/Serialization/ASTWriter.h" 15fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "ASTCommon.h" 1654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "clang/Sema/Sema.h" 1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Sema/IdentifierResolver.h" 1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/AST/ASTContext.h" 1950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/AST/Decl.h" 2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/AST/DeclContextInternals.h" 2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/AST/Expr.h" 2254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "clang/AST/Type.h" 2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/AST/TypeLocVisitor.h" 2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Serialization/ASTReader.h" 2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Lex/MacroInfo.h" 2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Lex/PreprocessingRecord.h" 2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Lex/Preprocessor.h" 2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Lex/HeaderSearch.h" 2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Basic/FileManager.h" 3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Basic/OnDiskHashTable.h" 3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Basic/SourceManager.h" 3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Basic/SourceManagerInternals.h" 3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Basic/TargetInfo.h" 3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "clang/Basic/Version.h" 3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "llvm/ADT/APFloat.h" 3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "llvm/ADT/APInt.h" 3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "llvm/ADT/StringExtras.h" 3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "llvm/Bitcode/BitstreamWriter.h" 3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "llvm/Support/MemoryBuffer.h" 4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "llvm/System/Path.h" 4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <cstdio> 4250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehousing namespace clang; 4350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehousing namespace clang::serialization; 4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate <typename T, typename Allocator> 4650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoT *data(std::vector<T, Allocator> &v) { 4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return v.empty() ? 0 : &v.front(); 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 4950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate <typename T, typename Allocator> 5050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst T *data(const std::vector<T, Allocator> &v) { 5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return v.empty() ? 0 : &v.front(); 5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//===----------------------------------------------------------------------===// 5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Type serialization 5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//===----------------------------------------------------------------------===// 5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehonamespace { 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho class ASTTypeWriter { 6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ASTWriter &Writer; 6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ASTWriter::RecordData &Record; 6254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 6354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius public: 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /// \brief Type code that corresponds to the record generated. 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho TypeCode Code; 6654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 6754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { } 6954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void VisitArrayType(const ArrayType *T); 7154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius void VisitFunctionType(const FunctionType *T); 7254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius void VisitTagType(const TagType *T); 7354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 7454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T); 7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define ABSTRACT_TYPE(Class, Base) 7654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "clang/AST/TypeNodes.def" 7754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius }; 7854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 7954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 8050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) { 8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(false && "Built-in types are never serialized"); 8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 8454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid ASTTypeWriter::VisitComplexType(const ComplexType *T) { 8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getElementType(), Record); 8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_COMPLEX; 8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 8954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid ASTTypeWriter::VisitPointerType(const PointerType *T) { 9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getPointeeType(), Record); 9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_POINTER; 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 9354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 9450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { 9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getPointeeType(), Record); 9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_BLOCK_POINTER; 9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 9950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) { 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getPointeeType(), Record); 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_LVALUE_REFERENCE; 10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) { 10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getPointeeType(), Record); 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_RVALUE_REFERENCE; 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) { 11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getPointeeType(), Record); 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(QualType(T->getClass(), 0), Record); 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_MEMBER_POINTER; 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitArrayType(const ArrayType *T) { 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getElementType(), Record); 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getSizeModifier()); // FIXME: stable values 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 12150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) { 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitArrayType(T); 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddAPInt(T->getSize(), Record); 12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_CONSTANT_ARRAY; 12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 12750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) { 12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitArrayType(T); 12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_INCOMPLETE_ARRAY; 13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 13250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { 13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitArrayType(T); 13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddSourceLocation(T->getLBracketLoc(), Record); 13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddSourceLocation(T->getRBracketLoc(), Record); 13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddStmt(T->getSizeExpr()); 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_VARIABLE_ARRAY; 13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 14050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitVectorType(const VectorType *T) { 14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getElementType(), Record); 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getNumElements()); 14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getAltiVecSpecific()); 14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_VECTOR; 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 14750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) { 14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitVectorType(T); 14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_EXT_VECTOR; 15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 151103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 152103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid ASTTypeWriter::VisitFunctionType(const FunctionType *T) { 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getResultType(), Record); 15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FunctionType::ExtInfo C = T->getExtInfo(); 15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(C.getNoReturn()); 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(C.getRegParm()); 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // FIXME: need to stabilize encoding of calling convention... 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(C.getCC()); 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitFunctionType(T); 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_FUNCTION_NO_PROTO; 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitFunctionType(T); 16854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(T->getNumArgs()); 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I) 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getArgType(I), Record); 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->isVariadic()); 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getTypeQuals()); 17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->hasExceptionSpec()); 17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->hasAnyExceptionSpec()); 17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getNumExceptions()); 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getExceptionType(I), Record); 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_FUNCTION_PROTO; 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 18150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddDeclRef(T->getDecl(), Record); 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_UNRESOLVED_USING; 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitTypedefType(const TypedefType *T) { 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddDeclRef(T->getDecl(), Record); 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(!T->isCanonicalUnqualified() && "Invalid typedef ?"); 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record); 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_TYPEDEF; 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) { 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddStmt(T->getUnderlyingExpr()); 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_TYPEOF_EXPR; 19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 19850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) { 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getUnderlyingType(), Record); 20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_TYPEOF; 20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 20350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { 20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddStmt(T->getUnderlyingExpr()); 20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_DECLTYPE; 20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 20850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitTagType(const TagType *T) { 20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->isDependentType()); 21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddDeclRef(T->getDecl(), Record); 21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(!T->isBeingDefined() && 21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho "Cannot serialize in the middle of a type definition"); 21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 21550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitRecordType(const RecordType *T) { 21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitTagType(T); 21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_RECORD; 21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTTypeWriter::VisitEnumType(const EnumType *T) { 22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitTagType(T); 22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_ENUM; 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoASTTypeWriter::VisitSubstTemplateTypeParmType( 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const SubstTemplateTypeParmType *T) { 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record); 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getReplacementType(), Record); 23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_SUBST_TEMPLATE_TYPE_PARM; 23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoASTTypeWriter::VisitTemplateSpecializationType( 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const TemplateSpecializationType *T) { 23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->isDependentType()); 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTemplateName(T->getTemplateName(), Record); 23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getNumArgs()); 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end(); 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ArgI != ArgE; ++ArgI) 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTemplateArgument(*ArgI, Record); 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType() 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho : T->getCanonicalTypeInternal(), 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record); 24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_TEMPLATE_SPECIALIZATION; 24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 24950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho VisitArrayType(T); 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddStmt(T->getSizeExpr()); 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddSourceRange(T->getBracketsRange(), Record); 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_DEPENDENT_SIZED_ARRAY; 25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 25750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoASTTypeWriter::VisitDependentSizedExtVectorType( 25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const DependentSizedExtVectorType *T) { 25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // FIXME: Serialize this type (C++ only) 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(false && "Cannot serialize dependent sized extended vector types"); 26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 26350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 26450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getDepth()); 26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->getIndex()); 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(T->isParameterPack()); 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddIdentifierRef(T->getName(), Record); 26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Code = TYPE_TEMPLATE_TYPE_PARM; 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 27154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 27254dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid 27354dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusASTTypeWriter::VisitDependentNameType(const DependentNameType *T) { 27454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(T->getKeyword()); 27559d709d503bab6e2b61931737e662dd293b40578ccornelius Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 27654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddIdentifierRef(T->getIdentifier(), Record); 27754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType() 27854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius : T->getCanonicalTypeInternal(), 279fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Record); 28059d709d503bab6e2b61931737e662dd293b40578ccornelius Code = TYPE_DEPENDENT_NAME; 28159d709d503bab6e2b61931737e662dd293b40578ccornelius} 28259d709d503bab6e2b61931737e662dd293b40578ccornelius 28359d709d503bab6e2b61931737e662dd293b40578ccorneliusvoid 28454dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusASTTypeWriter::VisitDependentTemplateSpecializationType( 28554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const DependentTemplateSpecializationType *T) { 28654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(T->getKeyword()); 28754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 28854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddIdentifierRef(T->getIdentifier(), Record); 28954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(T->getNumArgs()); 29054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for (DependentTemplateSpecializationType::iterator 29154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius I = T->begin(), E = T->end(); I != E; ++I) 292fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddTemplateArgument(*I, Record); 29354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION; 29454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 295fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 296fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { 297fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Record.push_back(T->getKeyword()); 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddNestedNameSpecifier(T->getQualifier(), Record); 29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTypeRef(T->getNamedType(), Record); 30054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Code = TYPE_ELABORATED; 30154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 30254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 30354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) { 30454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddDeclRef(T->getDecl(), Record); 30554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddTypeRef(T->getInjectedSpecializationType(), Record); 30654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Code = TYPE_INJECTED_CLASS_NAME; 30754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 30854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 30954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 31054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddDeclRef(T->getDecl(), Record); 31154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Code = TYPE_OBJC_INTERFACE; 31254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 31354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 31454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) { 31554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddTypeRef(T->getBaseType(), Record); 31654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(T->getNumProtocols()); 31754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for (ObjCObjectType::qual_iterator I = T->qual_begin(), 31854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius E = T->qual_end(); I != E; ++I) 31954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddDeclRef(*I, Record); 32054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Code = TYPE_OBJC_OBJECT; 32154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 32254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 32354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid 32454dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 32554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddTypeRef(T->getPointeeType(), Record); 32654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Code = TYPE_OBJC_OBJECT_POINTER; 32754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 32954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusnamespace { 33054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 33154dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusclass TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { 33254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ASTWriter &Writer; 33354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ASTWriter::RecordData &Record; 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 33550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) 33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho : Writer(Writer), Record(Record) { } 33854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 33954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define ABSTRACT_TYPELOC(CLASS, PARENT) 34054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define TYPELOC(CLASS, PARENT) \ 34159d709d503bab6e2b61931737e662dd293b40578ccornelius void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 34254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "clang/AST/TypeLocNodes.def" 34354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 34454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius void VisitArrayTypeLoc(ArrayTypeLoc TyLoc); 345fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc); 34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 34754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 34854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 35054dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 35154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // nothing to do 35254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 35354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 35454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getBuiltinLoc(), Record); 35559d709d503bab6e2b61931737e662dd293b40578ccornelius if (TL.needsExtraLocalData()) { 35654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(TL.getWrittenTypeSpec()); 35754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(TL.getWrittenSignSpec()); 35854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(TL.getWrittenWidthSpec()); 359fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Record.push_back(TL.hasModeAttr()); 36054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 36154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 36254dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { 36354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 36454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 36554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { 36654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getStarLoc(), Record); 36754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 36854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 36954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getCaretLoc(), Record); 37054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 37154dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 37254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getAmpLoc(), Record); 37354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 37454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 37554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record); 37654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 37854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getStarLoc(), Record); 37954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 38054dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { 38154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getLBracketLoc(), Record); 38254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getRBracketLoc(), Record); 38354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(TL.getSizeExpr() ? 1 : 0); 384103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (TL.getSizeExpr()) 38559d709d503bab6e2b61931737e662dd293b40578ccornelius Writer.AddStmt(TL.getSizeExpr()); 38654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 38754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { 38859d709d503bab6e2b61931737e662dd293b40578ccornelius VisitArrayTypeLoc(TL); 38954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 39059d709d503bab6e2b61931737e662dd293b40578ccorneliusvoid TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { 39159d709d503bab6e2b61931737e662dd293b40578ccornelius VisitArrayTypeLoc(TL); 39254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 39354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { 39454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius VisitArrayTypeLoc(TL); 39554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 39654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitDependentSizedArrayTypeLoc( 39754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius DependentSizedArrayTypeLoc TL) { 39854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius VisitArrayTypeLoc(TL); 39959d709d503bab6e2b61931737e662dd293b40578ccornelius} 40059d709d503bab6e2b61931737e662dd293b40578ccorneliusvoid TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( 40159d709d503bab6e2b61931737e662dd293b40578ccornelius DependentSizedExtVectorTypeLoc TL) { 40259d709d503bab6e2b61931737e662dd293b40578ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 40359d709d503bab6e2b61931737e662dd293b40578ccornelius} 40459d709d503bab6e2b61931737e662dd293b40578ccorneliusvoid TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { 40559d709d503bab6e2b61931737e662dd293b40578ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 40659d709d503bab6e2b61931737e662dd293b40578ccornelius} 40759d709d503bab6e2b61931737e662dd293b40578ccorneliusvoid TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { 40859d709d503bab6e2b61931737e662dd293b40578ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 40959d709d503bab6e2b61931737e662dd293b40578ccornelius} 41054dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { 41154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getLParenLoc(), Record); 41254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getRParenLoc(), Record); 41354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 41454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddDeclRef(TL.getArg(i), Record); 41554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 41654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { 41754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius VisitFunctionTypeLoc(TL); 41854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 41954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { 42054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius VisitFunctionTypeLoc(TL); 42154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 42254dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 42354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 42454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 42554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 42654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 42754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 428fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 42954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 43054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getLParenLoc(), Record); 43154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getRParenLoc(), Record); 43254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 43354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 43454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getTypeofLoc(), Record); 435fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getLParenLoc(), Record); 436fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getRParenLoc(), Record); 437fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record); 438fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 439fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 440fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 44154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 442fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { 443fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 444fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 445fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { 446fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 447fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 448fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 449fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 450fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 451fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( 452fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SubstTemplateTypeParmTypeLoc TL) { 453fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 454fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 455fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitTemplateSpecializationTypeLoc( 456fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius TemplateSpecializationTypeLoc TL) { 457fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record); 458fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 459fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 460fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 461fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(), 462fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius TL.getArgLoc(i).getLocInfo(), Record); 46354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 46454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { 465fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 466fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceRange(TL.getQualifierRange(), Record); 46754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 468fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 46954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 470fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 471fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { 472fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 473fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceRange(TL.getQualifierRange(), Record); 474fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 475fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 476fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( 477fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DependentTemplateSpecializationTypeLoc TL) { 478fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceLocation(TL.getKeywordLoc(), Record); 479fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Writer.AddSourceRange(TL.getQualifierRange(), Record); 48054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 48154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 48254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) 48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(), 48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho TL.getArgLoc(I).getLocInfo(), Record); 48659d709d503bab6e2b61931737e662dd293b40578ccornelius} 48754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 48854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Writer.AddSourceLocation(TL.getNameLoc(), Record); 489fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 49054dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(TL.hasBaseTypeAsWritten()); 49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddSourceLocation(TL.getLAngleLoc(), Record); 49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddSourceLocation(TL.getRAngleLoc(), Record); 49454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) 49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); 49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 49750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Writer.AddSourceLocation(TL.getStarLoc(), Record); 49954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 50054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 50154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//===----------------------------------------------------------------------===// 50254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// ASTWriter Implementation 50354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//===----------------------------------------------------------------------===// 50454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 50554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void EmitBlockID(unsigned ID, const char *Name, 50654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius llvm::BitstreamWriter &Stream, 50754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ASTWriter::RecordData &Record) { 50854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.clear(); 50954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(ID); 51054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); 51154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 51254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Emit the block name if present. 51354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (Name == 0 || Name[0] == 0) return; 51454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.clear(); 51554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius while (*Name) 51654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(*Name++); 51754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record); 51854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 51954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 520fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void EmitRecordID(unsigned ID, const char *Name, 521fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius llvm::BitstreamWriter &Stream, 522fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ASTWriter::RecordData &Record) { 523fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Record.clear(); 52454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(ID); 52554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius while (*Name) 52654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(*Name++); 52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record); 52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 53050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void AddStmtsExprs(llvm::BitstreamWriter &Stream, 53150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ASTWriter::RecordData &Record) { 53250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 53350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_STOP); 53450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_NULL_PTR); 53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_NULL); 53650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_COMPOUND); 53750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_CASE); 53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_DEFAULT); 53950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_LABEL); 54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_IF); 54150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_SWITCH); 54250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_WHILE); 54350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_DO); 54450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_FOR); 54550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_GOTO); 54650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_INDIRECT_GOTO); 54750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_CONTINUE); 54850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_BREAK); 54950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_RETURN); 55050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_DECL); 55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_ASM); 55250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_PREDEFINED); 55350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_DECL_REF); 55450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_INTEGER_LITERAL); 55550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_FLOATING_LITERAL); 55650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_IMAGINARY_LITERAL); 55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_STRING_LITERAL); 55850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CHARACTER_LITERAL); 55950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_PAREN); 56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_UNARY_OPERATOR); 56150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_SIZEOF_ALIGN_OF); 56250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_ARRAY_SUBSCRIPT); 56350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CALL); 56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_MEMBER); 56550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_BINARY_OPERATOR); 56650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR); 56750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CONDITIONAL_OPERATOR); 56850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_IMPLICIT_CAST); 56950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CSTYLE_CAST); 57050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_COMPOUND_LITERAL); 57150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_EXT_VECTOR_ELEMENT); 57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_INIT_LIST); 57350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_DESIGNATED_INIT); 57450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_IMPLICIT_VALUE_INIT); 57550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_VA_ARG); 57650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_ADDR_LABEL); 57750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_STMT); 57850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_TYPES_COMPATIBLE); 57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CHOOSE); 58050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_GNU_NULL); 58150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_SHUFFLE_VECTOR); 58250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_BLOCK); 58350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_BLOCK_DECL_REF); 58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_STRING_LITERAL); 58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_ENCODE); 58650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_SELECTOR_EXPR); 58750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_PROTOCOL_EXPR); 58850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_IVAR_REF_EXPR); 58950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_PROPERTY_REF_EXPR); 59050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_KVC_REF_EXPR); 59150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_MESSAGE_EXPR); 59250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_OBJC_SUPER_EXPR); 59350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_OBJC_FOR_COLLECTION); 59459d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(STMT_OBJC_CATCH); 59559d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(STMT_OBJC_FINALLY); 59650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_OBJC_AT_TRY); 59750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_OBJC_AT_SYNCHRONIZED); 59850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STMT_OBJC_AT_THROW); 59950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CXX_OPERATOR_CALL); 60050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CXX_CONSTRUCT); 60150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CXX_STATIC_CAST); 60250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CXX_DYNAMIC_CAST); 60350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXPR_CXX_REINTERPRET_CAST); 604103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(EXPR_CXX_CONST_CAST); 60559d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(EXPR_CXX_FUNCTIONAL_CAST); 60659d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(EXPR_CXX_BOOL_LITERAL); 607103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(EXPR_CXX_NULL_PTR_LITERAL); 60859d709d503bab6e2b61931737e662dd293b40578ccornelius#undef RECORD 60959d709d503bab6e2b61931737e662dd293b40578ccornelius} 610103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 611103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid ASTWriter::WriteBlockInfoBlock() { 612103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RecordData Record; 613103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3); 614103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 615103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record) 616103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define RECORD(X) EmitRecordID(X, #X, Stream, Record) 617103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 618103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // AST Top-Level Block. 619103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius BLOCK(AST_BLOCK); 620103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(ORIGINAL_FILE_NAME); 621103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(TYPE_OFFSET); 622103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(DECL_OFFSET); 623103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(LANGUAGE_OPTIONS); 624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho RECORD(METADATA); 625103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(IDENTIFIER_OFFSET); 626103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius RECORD(IDENTIFIER_TABLE); 62750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(EXTERNAL_DEFINITIONS); 62850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(SPECIAL_TYPES); 62950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STATISTICS); 63050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TENTATIVE_DEFINITIONS); 63150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(UNUSED_FILESCOPED_DECLS); 63250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS); 63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(SELECTOR_OFFSETS); 63450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(METHOD_POOL); 63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(PP_COUNTER_VALUE); 63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(SOURCE_LOCATION_OFFSETS); 63750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(SOURCE_LOCATION_PRELOADS); 63850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(STAT_CACHE); 63954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(EXT_VECTOR_DECLS); 64050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(VERSION_CONTROL_BRANCH_REVISION); 64150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(MACRO_DEFINITION_OFFSETS); 64254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(CHAINED_METADATA); 64354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(REFERENCED_SELECTOR_POOL); 64450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 64550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // SourceManager Block. 64650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho BLOCK(SOURCE_MANAGER_BLOCK); 64750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(SM_SLOC_FILE_ENTRY); 64859d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(SM_SLOC_BUFFER_ENTRY); 64959d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(SM_SLOC_BUFFER_BLOB); 65059d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(SM_SLOC_INSTANTIATION_ENTRY); 65159d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(SM_LINE_TABLE); 65259d709d503bab6e2b61931737e662dd293b40578ccornelius 65359d709d503bab6e2b61931737e662dd293b40578ccornelius // Preprocessor Block. 65459d709d503bab6e2b61931737e662dd293b40578ccornelius BLOCK(PREPROCESSOR_BLOCK); 65559d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(PP_MACRO_OBJECT_LIKE); 65659d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(PP_MACRO_FUNCTION_LIKE); 65759d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(PP_TOKEN); 65859d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(PP_MACRO_INSTANTIATION); 65959d709d503bab6e2b61931737e662dd293b40578ccornelius RECORD(PP_MACRO_DEFINITION); 66059d709d503bab6e2b61931737e662dd293b40578ccornelius 66159d709d503bab6e2b61931737e662dd293b40578ccornelius // Decls and Types block. 66254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius BLOCK(DECLTYPES_BLOCK); 66354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(TYPE_EXT_QUAL); 66450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_COMPLEX); 66550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_POINTER); 66650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_BLOCK_POINTER); 66750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_LVALUE_REFERENCE); 66850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_RVALUE_REFERENCE); 66954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(TYPE_MEMBER_POINTER); 67050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_CONSTANT_ARRAY); 67150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_INCOMPLETE_ARRAY); 67254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(TYPE_VARIABLE_ARRAY); 67350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_VECTOR); 67450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_EXT_VECTOR); 67550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_FUNCTION_PROTO); 67654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(TYPE_FUNCTION_NO_PROTO); 67750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_TYPEDEF); 67850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_TYPEOF_EXPR); 67950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_TYPEOF); 68050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_RECORD); 68150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(TYPE_ENUM); 68254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(TYPE_OBJC_INTERFACE); 68354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(TYPE_OBJC_OBJECT); 68454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(TYPE_OBJC_OBJECT_POINTER); 68554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_ATTR); 68654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_TRANSLATION_UNIT); 68750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_TYPEDEF); 68850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_ENUM); 68950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_RECORD); 69050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_ENUM_CONSTANT); 69150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_FUNCTION); 69254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_OBJC_METHOD); 69354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_OBJC_INTERFACE); 69450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_PROTOCOL); 69550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_IVAR); 69650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_AT_DEFS_FIELD); 69750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_CLASS); 69850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_FORWARD_PROTOCOL); 69954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_OBJC_CATEGORY); 70054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_OBJC_CATEGORY_IMPL); 70154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_OBJC_IMPLEMENTATION); 70250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_COMPATIBLE_ALIAS); 70350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_PROPERTY); 70450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_OBJC_PROPERTY_IMPL); 70550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_FIELD); 70650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_VAR); 70754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_IMPLICIT_PARAM); 70854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RECORD(DECL_PARM_VAR); 70950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_FILE_SCOPE_ASM); 71050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_BLOCK); 71150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_CONTEXT_LEXICAL); 71250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RECORD(DECL_CONTEXT_VISIBLE); 71350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Statements and Exprs can occur in the Decls and Types block. 71454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius AddStmtsExprs(Stream, Record); 71554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#undef RECORD 71650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#undef BLOCK 71750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Stream.ExitBlock(); 71850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 71950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 72050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// \brief Adjusts the given filename to only write out the portion of the 72154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius/// filename that is not part of the system root directory. 72254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius/// 72350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// \param Filename the file name to adjust. 72450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// 72550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and 72650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// the returned filename will be adjusted by this system root. 72750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// 72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// \returns either the original filename (if it needs no adjustment) or the 72954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius/// adjusted filename (which points into the @p Filename parameter). 730fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic const char * 73150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoadjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) { 73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(Filename && "No file name to adjust?"); 73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (!isysroot) 73550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return Filename; 73650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 73750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Verify that the filename and the system root have the same prefix. 73854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius unsigned Pos = 0; 73954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for (; Filename[Pos] && isysroot[Pos]; ++Pos) 74054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (Filename[Pos] != isysroot[Pos]) 74154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return Filename; // Prefixes don't match. 74254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 74354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // We hit the end of the filename before we hit the end of the system root. 74454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (!Filename[Pos]) 74554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return Filename; 74654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 74754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // If the file name has a '/' at the current position, skip over the '/'. 74850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // We distinguish sysroot-based includes from absolute includes by the 74950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // absence of '/' at the beginning of sysroot-based includes. 75050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (Filename[Pos] == '/') 75150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++Pos; 75250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 75350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return Filename + Pos; 75450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 75550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 75654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius/// \brief Write the AST metadata (e.g., i686-apple-darwin9). 75750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot) { 75850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho using namespace llvm; 75950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 76050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Metadata 76150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const TargetInfo &Target = Context.Target; 76250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev(); 76350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MetaAbbrev->Add(BitCodeAbbrevOp( 76450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Chain ? CHAINED_METADATA : METADATA)); 76550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major 76650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor 76750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major 76850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor 76954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable 77054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Target triple or chained PCH name 77154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 77254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev); 77354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 77454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RecordData Record; 77554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(Chain ? CHAINED_METADATA : METADATA); 77654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(VERSION_MAJOR); 77754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(VERSION_MINOR); 77854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(CLANG_VERSION_MAJOR); 77954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(CLANG_VERSION_MINOR); 78054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(isysroot != 0); 78154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // FIXME: This writes the absolute path for chained headers. 78254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple(); 78354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr); 78450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 78550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Original file name 78650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SourceManager &SM = Context.getSourceManager(); 78750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { 78854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev(); 78950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE_NAME)); 79050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 79150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev); 79250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho llvm::sys::Path MainFilePath(MainFile->getName()); 79450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 79550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MainFilePath.makeAbsolute(); 79654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 79750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *MainFileNameStr = MainFilePath.c_str(); 79850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, 79950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho isysroot); 80050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RecordData Record; 80150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(ORIGINAL_FILE_NAME); 80250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); 80350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 80454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 80554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Repository branch/version information. 80654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev(); 80754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RepoAbbrev->Add(BitCodeAbbrevOp(VERSION_CONTROL_BRANCH_REVISION)); 80854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag 80954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev); 81054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.clear(); 81154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(VERSION_CONTROL_BRANCH_REVISION); 81254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Stream.EmitRecordWithBlob(RepoAbbrevCode, Record, 81354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius getClangFullRepositoryVersion()); 81454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 81550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 81650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// \brief Write the LangOptions structure. 81750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { 81850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho RecordData Record; 81950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.Trigraphs); 82050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments. 82150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers. 82250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode. 82350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc) 82450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.GNUKeywords); // Allow GNU-extension keywords 82550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'. 82650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.Digraphs); // C94, C99 and C++ 82750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants. 82850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.C99); // C99 Support 82950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.Microsoft); // Microsoft extensions. 83050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.CPlusPlus); // C++ Support 83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support 83254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords. 83350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 83450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled. 83550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled. 83650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C 83750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // modern abi enabled. 83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced 83950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // modern abi enabled. 84050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled.. 84150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 84250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings 84350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.WritableStrings); // Allow writable strings 84450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.LaxVectorConversions); 84550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.AltiVec); 84650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.Exceptions); // Support exception handling. 84750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.SjLjExceptions); 84850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 84950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime. 85054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(LangOpts.Freestanding); // Freestanding implementation 85150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin) 85250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 85350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Whether static initializers are protected by locks. 85450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ThreadsafeStatics); 85550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.POSIXThreads); 85650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.Blocks); // block extension to C 85750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if 85850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // they are unused. 85950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.MathErrno); // Math functions must respect errno 86050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // (modulo the platform support). 86150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 86250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.getSignedOverflowBehavior()); 86350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.HeinousExtensions); 86450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 86550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined. 86650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be 86750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // defined. 86854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as 86950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // opposed to __DYNAMIC__). 87050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero. 87150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 87250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be 87350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // used (instead of C99 semantics). 87450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined. 87550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.AccessControl); // Whether C++ access control should 87650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // be enabled. 87754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or 87850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // unsigned type 87950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ShortWChar); // force wchar_t to be unsigned short 88050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.getGCMode()); 88150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.getVisibilityMode()); 88250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.getStackProtectorMode()); 88350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.InstantiationDepth); 88450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.OpenCL); 88550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.CatchUndefined); 88650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.ElideConstructors); 88750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Record.push_back(LangOpts.SpellChecking); 88850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Stream.EmitRecord(LANGUAGE_OPTIONS, Record); 88950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 89050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 89150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//===----------------------------------------------------------------------===// 89250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// stat cache Serialization 89350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//===----------------------------------------------------------------------===// 89450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 89554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusnamespace { 89650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Trait used for the on-disk hash table of stat cache results. 89750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass ASTStatCacheTrait { 89850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 89950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typedef const char * key_type; 90050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typedef key_type key_type_ref; 90150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 90250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typedef std::pair<int, struct stat> data_type; 90350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typedef const data_type& data_type_ref; 90450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 90550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho static unsigned ComputeHash(const char *path) { 90650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return llvm::HashString(path); 90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 90850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 90950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho std::pair<unsigned,unsigned> 91050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho EmitKeyDataLength(llvm::raw_ostream& Out, const char *path, 91150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho data_type_ref Data) { 91250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho unsigned StrLen = strlen(path); 91354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius clang::io::Emit16(Out, StrLen); 91450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho unsigned DataLen = 1; // result value 91550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (Data.first == 0) 91650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DataLen += 4 + 4 + 2 + 8 + 8; 91750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho clang::io::Emit8(Out, DataLen); 91850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return std::make_pair(StrLen + 1, DataLen); 91950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 92050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 92150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) { 92250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Out.write(path, KeyLen); 92350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 92450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 92550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void EmitData(llvm::raw_ostream& Out, key_type_ref, 92650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho data_type_ref Data, unsigned DataLen) { 92750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho using namespace clang::io; 92850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint64_t Start = Out.tell(); (void)Start; 92950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 93050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Result of stat() 93154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius Emit8(Out, Data.first? 1 : 0); 93250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 93350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (Data.first == 0) { 93450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Emit32(Out, (uint32_t) Data.second.st_ino); 93550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Emit32(Out, (uint32_t) Data.second.st_dev); 93650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Emit16(Out, (uint16_t) Data.second.st_mode); 93750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Emit64(Out, (uint64_t) Data.second.st_mtime); 93850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Emit64(Out, (uint64_t) Data.second.st_size); 93950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 94050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 94150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(Out.tell() - Start == DataLen && "Wrong data length"); 94250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 94350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 94450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} // end anonymous namespace 94550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 94650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/// \brief Write the stat() system call cache to the AST file. 94750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) { 94850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Build the on-disk hash table containing information about every 94950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // stat() call. 95050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho OnDiskChainedHashTableGenerator<ASTStatCacheTrait> Generator; 95150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho unsigned NumStatEntries = 0; 952 for (MemorizeStatCalls::iterator Stat = StatCalls.begin(), 953 StatEnd = StatCalls.end(); 954 Stat != StatEnd; ++Stat, ++NumStatEntries) { 955 const char *Filename = Stat->first(); 956 Generator.insert(Filename, Stat->second); 957 } 958 959 // Create the on-disk hash table in a buffer. 960 llvm::SmallString<4096> StatCacheData; 961 uint32_t BucketOffset; 962 { 963 llvm::raw_svector_ostream Out(StatCacheData); 964 // Make sure that no bucket is at offset 0 965 clang::io::Emit32(Out, 0); 966 BucketOffset = Generator.Emit(Out); 967 } 968 969 // Create a blob abbreviation 970 using namespace llvm; 971 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 972 Abbrev->Add(BitCodeAbbrevOp(STAT_CACHE)); 973 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 974 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 975 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 976 unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev); 977 978 // Write the stat cache 979 RecordData Record; 980 Record.push_back(STAT_CACHE); 981 Record.push_back(BucketOffset); 982 Record.push_back(NumStatEntries); 983 Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str()); 984} 985 986//===----------------------------------------------------------------------===// 987// Source Manager Serialization 988//===----------------------------------------------------------------------===// 989 990/// \brief Create an abbreviation for the SLocEntry that refers to a 991/// file. 992static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { 993 using namespace llvm; 994 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 995 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY)); 996 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 997 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 998 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 999 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1000 // FileEntry fields. 1001 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size 1002 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time 1003 // HeaderFileInfo fields. 1004 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImport 1005 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // DirInfo 1006 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumIncludes 1007 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // ControllingMacro 1008 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 1009 return Stream.EmitAbbrev(Abbrev); 1010} 1011 1012/// \brief Create an abbreviation for the SLocEntry that refers to a 1013/// buffer. 1014static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { 1015 using namespace llvm; 1016 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1017 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY)); 1018 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1019 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 1020 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic 1021 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1022 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob 1023 return Stream.EmitAbbrev(Abbrev); 1024} 1025 1026/// \brief Create an abbreviation for the SLocEntry that refers to a 1027/// buffer's blob. 1028static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) { 1029 using namespace llvm; 1030 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1031 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_BLOB)); 1032 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob 1033 return Stream.EmitAbbrev(Abbrev); 1034} 1035 1036/// \brief Create an abbreviation for the SLocEntry that refers to an 1037/// buffer. 1038static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) { 1039 using namespace llvm; 1040 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1041 Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_INSTANTIATION_ENTRY)); 1042 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1043 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location 1044 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location 1045 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location 1046 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length 1047 return Stream.EmitAbbrev(Abbrev); 1048} 1049 1050/// \brief Writes the block containing the serialized form of the 1051/// source manager. 1052/// 1053/// TODO: We should probably use an on-disk hash table (stored in a 1054/// blob), indexed based on the file name, so that we only create 1055/// entries for files that we actually need. In the common case (no 1056/// errors), we probably won't have to create file entries for any of 1057/// the files in the AST. 1058void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, 1059 const Preprocessor &PP, 1060 const char *isysroot) { 1061 RecordData Record; 1062 1063 // Enter the source manager block. 1064 Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 3); 1065 1066 // Abbreviations for the various kinds of source-location entries. 1067 unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream); 1068 unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream); 1069 unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream); 1070 unsigned SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream); 1071 1072 // Write the line table. 1073 if (SourceMgr.hasLineTable()) { 1074 LineTableInfo &LineTable = SourceMgr.getLineTable(); 1075 1076 // Emit the file names 1077 Record.push_back(LineTable.getNumFilenames()); 1078 for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) { 1079 // Emit the file name 1080 const char *Filename = LineTable.getFilename(I); 1081 Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 1082 unsigned FilenameLen = Filename? strlen(Filename) : 0; 1083 Record.push_back(FilenameLen); 1084 if (FilenameLen) 1085 Record.insert(Record.end(), Filename, Filename + FilenameLen); 1086 } 1087 1088 // Emit the line entries 1089 for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end(); 1090 L != LEnd; ++L) { 1091 // Emit the file ID 1092 Record.push_back(L->first); 1093 1094 // Emit the line entries 1095 Record.push_back(L->second.size()); 1096 for (std::vector<LineEntry>::iterator LE = L->second.begin(), 1097 LEEnd = L->second.end(); 1098 LE != LEEnd; ++LE) { 1099 Record.push_back(LE->FileOffset); 1100 Record.push_back(LE->LineNo); 1101 Record.push_back(LE->FilenameID); 1102 Record.push_back((unsigned)LE->FileKind); 1103 Record.push_back(LE->IncludeOffset); 1104 } 1105 } 1106 Stream.EmitRecord(SM_LINE_TABLE, Record); 1107 } 1108 1109 // Write out the source location entry table. We skip the first 1110 // entry, which is always the same dummy entry. 1111 std::vector<uint32_t> SLocEntryOffsets; 1112 RecordData PreloadSLocs; 1113 unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0; 1114 SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID); 1115 for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size(); 1116 I != N; ++I) { 1117 // Get this source location entry. 1118 const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I); 1119 1120 // Record the offset of this source-location entry. 1121 SLocEntryOffsets.push_back(Stream.GetCurrentBitNo()); 1122 1123 // Figure out which record code to use. 1124 unsigned Code; 1125 if (SLoc->isFile()) { 1126 if (SLoc->getFile().getContentCache()->Entry) 1127 Code = SM_SLOC_FILE_ENTRY; 1128 else 1129 Code = SM_SLOC_BUFFER_ENTRY; 1130 } else 1131 Code = SM_SLOC_INSTANTIATION_ENTRY; 1132 Record.clear(); 1133 Record.push_back(Code); 1134 1135 Record.push_back(SLoc->getOffset()); 1136 if (SLoc->isFile()) { 1137 const SrcMgr::FileInfo &File = SLoc->getFile(); 1138 Record.push_back(File.getIncludeLoc().getRawEncoding()); 1139 Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding 1140 Record.push_back(File.hasLineDirectives()); 1141 1142 const SrcMgr::ContentCache *Content = File.getContentCache(); 1143 if (Content->Entry) { 1144 // The source location entry is a file. The blob associated 1145 // with this entry is the file name. 1146 1147 // Emit size/modification time for this file. 1148 Record.push_back(Content->Entry->getSize()); 1149 Record.push_back(Content->Entry->getModificationTime()); 1150 1151 // Emit header-search information associated with this file. 1152 HeaderFileInfo HFI; 1153 HeaderSearch &HS = PP.getHeaderSearchInfo(); 1154 if (Content->Entry->getUID() < HS.header_file_size()) 1155 HFI = HS.header_file_begin()[Content->Entry->getUID()]; 1156 Record.push_back(HFI.isImport); 1157 Record.push_back(HFI.DirInfo); 1158 Record.push_back(HFI.NumIncludes); 1159 AddIdentifierRef(HFI.ControllingMacro, Record); 1160 1161 // Turn the file name into an absolute path, if it isn't already. 1162 const char *Filename = Content->Entry->getName(); 1163 llvm::sys::Path FilePath(Filename, strlen(Filename)); 1164 FilePath.makeAbsolute(); 1165 Filename = FilePath.c_str(); 1166 1167 Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); 1168 Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename); 1169 1170 // FIXME: For now, preload all file source locations, so that 1171 // we get the appropriate File entries in the reader. This is 1172 // a temporary measure. 1173 PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); 1174 } else { 1175 // The source location entry is a buffer. The blob associated 1176 // with this entry contains the contents of the buffer. 1177 1178 // We add one to the size so that we capture the trailing NULL 1179 // that is required by llvm::MemoryBuffer::getMemBuffer (on 1180 // the reader side). 1181 const llvm::MemoryBuffer *Buffer 1182 = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); 1183 const char *Name = Buffer->getBufferIdentifier(); 1184 Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record, 1185 llvm::StringRef(Name, strlen(Name) + 1)); 1186 Record.clear(); 1187 Record.push_back(SM_SLOC_BUFFER_BLOB); 1188 Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, 1189 llvm::StringRef(Buffer->getBufferStart(), 1190 Buffer->getBufferSize() + 1)); 1191 1192 if (strcmp(Name, "<built-in>") == 0) 1193 PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); 1194 } 1195 } else { 1196 // The source location entry is an instantiation. 1197 const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation(); 1198 Record.push_back(Inst.getSpellingLoc().getRawEncoding()); 1199 Record.push_back(Inst.getInstantiationLocStart().getRawEncoding()); 1200 Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding()); 1201 1202 // Compute the token length for this macro expansion. 1203 unsigned NextOffset = SourceMgr.getNextOffset(); 1204 if (I + 1 != N) 1205 NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset(); 1206 Record.push_back(NextOffset - SLoc->getOffset() - 1); 1207 Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record); 1208 } 1209 } 1210 1211 Stream.ExitBlock(); 1212 1213 if (SLocEntryOffsets.empty()) 1214 return; 1215 1216 // Write the source-location offsets table into the AST block. This 1217 // table is used for lazily loading source-location information. 1218 using namespace llvm; 1219 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1220 Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS)); 1221 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs 1222 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset 1223 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets 1224 unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev); 1225 1226 Record.clear(); 1227 Record.push_back(SOURCE_LOCATION_OFFSETS); 1228 Record.push_back(SLocEntryOffsets.size()); 1229 Record.push_back(SourceMgr.getNextOffset()); 1230 Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, 1231 (const char *)data(SLocEntryOffsets), 1232 SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0])); 1233 1234 // Write the source location entry preloads array, telling the AST 1235 // reader which source locations entries it should load eagerly. 1236 Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs); 1237} 1238 1239//===----------------------------------------------------------------------===// 1240// Preprocessor Serialization 1241//===----------------------------------------------------------------------===// 1242 1243/// \brief Writes the block containing the serialized form of the 1244/// preprocessor. 1245/// 1246void ASTWriter::WritePreprocessor(const Preprocessor &PP) { 1247 RecordData Record; 1248 1249 // If the preprocessor __COUNTER__ value has been bumped, remember it. 1250 if (PP.getCounterValue() != 0) { 1251 Record.push_back(PP.getCounterValue()); 1252 Stream.EmitRecord(PP_COUNTER_VALUE, Record); 1253 Record.clear(); 1254 } 1255 1256 // Enter the preprocessor block. 1257 Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 2); 1258 1259 // If the AST file contains __DATE__ or __TIME__ emit a warning about this. 1260 // FIXME: use diagnostics subsystem for localization etc. 1261 if (PP.SawDateOrTime()) 1262 fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n"); 1263 1264 // Loop over all the macro definitions that are live at the end of the file, 1265 // emitting each to the PP section. 1266 PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); 1267 for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); 1268 I != E; ++I) { 1269 // FIXME: This emits macros in hash table order, we should do it in a stable 1270 // order so that output is reproducible. 1271 MacroInfo *MI = I->second; 1272 1273 // Don't emit builtin macros like __LINE__ to the AST file unless they have 1274 // been redefined by the header (in which case they are not isBuiltinMacro). 1275 // Also skip macros from a AST file if we're chaining. 1276 if (MI->isBuiltinMacro() || (Chain && MI->isFromAST())) 1277 continue; 1278 1279 AddIdentifierRef(I->first, Record); 1280 MacroOffsets[I->first] = Stream.GetCurrentBitNo(); 1281 Record.push_back(MI->getDefinitionLoc().getRawEncoding()); 1282 Record.push_back(MI->isUsed()); 1283 1284 unsigned Code; 1285 if (MI->isObjectLike()) { 1286 Code = PP_MACRO_OBJECT_LIKE; 1287 } else { 1288 Code = PP_MACRO_FUNCTION_LIKE; 1289 1290 Record.push_back(MI->isC99Varargs()); 1291 Record.push_back(MI->isGNUVarargs()); 1292 Record.push_back(MI->getNumArgs()); 1293 for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end(); 1294 I != E; ++I) 1295 AddIdentifierRef(*I, Record); 1296 } 1297 1298 // If we have a detailed preprocessing record, record the macro definition 1299 // ID that corresponds to this macro. 1300 if (PPRec) 1301 Record.push_back(getMacroDefinitionID(PPRec->findMacroDefinition(MI))); 1302 1303 Stream.EmitRecord(Code, Record); 1304 Record.clear(); 1305 1306 // Emit the tokens array. 1307 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) { 1308 // Note that we know that the preprocessor does not have any annotation 1309 // tokens in it because they are created by the parser, and thus can't be 1310 // in a macro definition. 1311 const Token &Tok = MI->getReplacementToken(TokNo); 1312 1313 Record.push_back(Tok.getLocation().getRawEncoding()); 1314 Record.push_back(Tok.getLength()); 1315 1316 // FIXME: When reading literal tokens, reconstruct the literal pointer if 1317 // it is needed. 1318 AddIdentifierRef(Tok.getIdentifierInfo(), Record); 1319 1320 // FIXME: Should translate token kind to a stable encoding. 1321 Record.push_back(Tok.getKind()); 1322 // FIXME: Should translate token flags to a stable encoding. 1323 Record.push_back(Tok.getFlags()); 1324 1325 Stream.EmitRecord(PP_TOKEN, Record); 1326 Record.clear(); 1327 } 1328 ++NumMacros; 1329 } 1330 1331 // If the preprocessor has a preprocessing record, emit it. 1332 unsigned NumPreprocessingRecords = 0; 1333 if (PPRec) { 1334 for (PreprocessingRecord::iterator E = PPRec->begin(), EEnd = PPRec->end(); 1335 E != EEnd; ++E) { 1336 Record.clear(); 1337 1338 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { 1339 Record.push_back(NumPreprocessingRecords++); 1340 AddSourceLocation(MI->getSourceRange().getBegin(), Record); 1341 AddSourceLocation(MI->getSourceRange().getEnd(), Record); 1342 AddIdentifierRef(MI->getName(), Record); 1343 Record.push_back(getMacroDefinitionID(MI->getDefinition())); 1344 Stream.EmitRecord(PP_MACRO_INSTANTIATION, Record); 1345 continue; 1346 } 1347 1348 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { 1349 // Record this macro definition's location. 1350 IdentID ID = getMacroDefinitionID(MD); 1351 if (ID != MacroDefinitionOffsets.size()) { 1352 if (ID > MacroDefinitionOffsets.size()) 1353 MacroDefinitionOffsets.resize(ID + 1); 1354 1355 MacroDefinitionOffsets[ID] = Stream.GetCurrentBitNo(); 1356 } else 1357 MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); 1358 1359 Record.push_back(NumPreprocessingRecords++); 1360 Record.push_back(ID); 1361 AddSourceLocation(MD->getSourceRange().getBegin(), Record); 1362 AddSourceLocation(MD->getSourceRange().getEnd(), Record); 1363 AddIdentifierRef(MD->getName(), Record); 1364 AddSourceLocation(MD->getLocation(), Record); 1365 Stream.EmitRecord(PP_MACRO_DEFINITION, Record); 1366 continue; 1367 } 1368 } 1369 } 1370 1371 Stream.ExitBlock(); 1372 1373 // Write the offsets table for the preprocessing record. 1374 if (NumPreprocessingRecords > 0) { 1375 // Write the offsets table for identifier IDs. 1376 using namespace llvm; 1377 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1378 Abbrev->Add(BitCodeAbbrevOp(MACRO_DEFINITION_OFFSETS)); 1379 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of records 1380 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs 1381 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1382 unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1383 1384 Record.clear(); 1385 Record.push_back(MACRO_DEFINITION_OFFSETS); 1386 Record.push_back(NumPreprocessingRecords); 1387 Record.push_back(MacroDefinitionOffsets.size()); 1388 Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record, 1389 (const char *)data(MacroDefinitionOffsets), 1390 MacroDefinitionOffsets.size() * sizeof(uint32_t)); 1391 } 1392} 1393 1394//===----------------------------------------------------------------------===// 1395// Type Serialization 1396//===----------------------------------------------------------------------===// 1397 1398/// \brief Write the representation of a type to the AST stream. 1399void ASTWriter::WriteType(QualType T) { 1400 TypeIdx &Idx = TypeIdxs[T]; 1401 if (Idx.getIndex() == 0) // we haven't seen this type before. 1402 Idx = TypeIdx(NextTypeID++); 1403 1404 // Record the offset for this type. 1405 unsigned Index = Idx.getIndex() - FirstTypeID; 1406 if (TypeOffsets.size() == Index) 1407 TypeOffsets.push_back(Stream.GetCurrentBitNo()); 1408 else if (TypeOffsets.size() < Index) { 1409 TypeOffsets.resize(Index + 1); 1410 TypeOffsets[Index] = Stream.GetCurrentBitNo(); 1411 } 1412 1413 RecordData Record; 1414 1415 // Emit the type's representation. 1416 ASTTypeWriter W(*this, Record); 1417 1418 if (T.hasLocalNonFastQualifiers()) { 1419 Qualifiers Qs = T.getLocalQualifiers(); 1420 AddTypeRef(T.getLocalUnqualifiedType(), Record); 1421 Record.push_back(Qs.getAsOpaqueValue()); 1422 W.Code = TYPE_EXT_QUAL; 1423 } else { 1424 switch (T->getTypeClass()) { 1425 // For all of the concrete, non-dependent types, call the 1426 // appropriate visitor function. 1427#define TYPE(Class, Base) \ 1428 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break; 1429#define ABSTRACT_TYPE(Class, Base) 1430#include "clang/AST/TypeNodes.def" 1431 } 1432 } 1433 1434 // Emit the serialized record. 1435 Stream.EmitRecord(W.Code, Record); 1436 1437 // Flush any expressions that were written as part of this type. 1438 FlushStmts(); 1439} 1440 1441//===----------------------------------------------------------------------===// 1442// Declaration Serialization 1443//===----------------------------------------------------------------------===// 1444 1445/// \brief Write the block containing all of the declaration IDs 1446/// lexically declared within the given DeclContext. 1447/// 1448/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the 1449/// bistream, or 0 if no block was written. 1450uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, 1451 DeclContext *DC) { 1452 if (DC->decls_empty()) 1453 return 0; 1454 1455 uint64_t Offset = Stream.GetCurrentBitNo(); 1456 RecordData Record; 1457 Record.push_back(DECL_CONTEXT_LEXICAL); 1458 llvm::SmallVector<DeclID, 64> Decls; 1459 for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); 1460 D != DEnd; ++D) 1461 Decls.push_back(GetDeclRef(*D)); 1462 1463 ++NumLexicalDeclContexts; 1464 Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, 1465 reinterpret_cast<char*>(Decls.data()), Decls.size() * sizeof(DeclID)); 1466 return Offset; 1467} 1468 1469void ASTWriter::WriteTypeDeclOffsets() { 1470 using namespace llvm; 1471 RecordData Record; 1472 1473 // Write the type offsets array 1474 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1475 Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET)); 1476 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types 1477 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block 1478 unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1479 Record.clear(); 1480 Record.push_back(TYPE_OFFSET); 1481 Record.push_back(TypeOffsets.size()); 1482 Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, 1483 (const char *)data(TypeOffsets), 1484 TypeOffsets.size() * sizeof(TypeOffsets[0])); 1485 1486 // Write the declaration offsets array 1487 Abbrev = new BitCodeAbbrev(); 1488 Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); 1489 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations 1490 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block 1491 unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1492 Record.clear(); 1493 Record.push_back(DECL_OFFSET); 1494 Record.push_back(DeclOffsets.size()); 1495 Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, 1496 (const char *)data(DeclOffsets), 1497 DeclOffsets.size() * sizeof(DeclOffsets[0])); 1498} 1499 1500//===----------------------------------------------------------------------===// 1501// Global Method Pool and Selector Serialization 1502//===----------------------------------------------------------------------===// 1503 1504namespace { 1505// Trait used for the on-disk hash table used in the method pool. 1506class ASTMethodPoolTrait { 1507 ASTWriter &Writer; 1508 1509public: 1510 typedef Selector key_type; 1511 typedef key_type key_type_ref; 1512 1513 struct data_type { 1514 SelectorID ID; 1515 ObjCMethodList Instance, Factory; 1516 }; 1517 typedef const data_type& data_type_ref; 1518 1519 explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { } 1520 1521 static unsigned ComputeHash(Selector Sel) { 1522 return serialization::ComputeHash(Sel); 1523 } 1524 1525 std::pair<unsigned,unsigned> 1526 EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel, 1527 data_type_ref Methods) { 1528 unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4); 1529 clang::io::Emit16(Out, KeyLen); 1530 unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts 1531 for (const ObjCMethodList *Method = &Methods.Instance; Method; 1532 Method = Method->Next) 1533 if (Method->Method) 1534 DataLen += 4; 1535 for (const ObjCMethodList *Method = &Methods.Factory; Method; 1536 Method = Method->Next) 1537 if (Method->Method) 1538 DataLen += 4; 1539 clang::io::Emit16(Out, DataLen); 1540 return std::make_pair(KeyLen, DataLen); 1541 } 1542 1543 void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) { 1544 uint64_t Start = Out.tell(); 1545 assert((Start >> 32) == 0 && "Selector key offset too large"); 1546 Writer.SetSelectorOffset(Sel, Start); 1547 unsigned N = Sel.getNumArgs(); 1548 clang::io::Emit16(Out, N); 1549 if (N == 0) 1550 N = 1; 1551 for (unsigned I = 0; I != N; ++I) 1552 clang::io::Emit32(Out, 1553 Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I))); 1554 } 1555 1556 void EmitData(llvm::raw_ostream& Out, key_type_ref, 1557 data_type_ref Methods, unsigned DataLen) { 1558 uint64_t Start = Out.tell(); (void)Start; 1559 clang::io::Emit32(Out, Methods.ID); 1560 unsigned NumInstanceMethods = 0; 1561 for (const ObjCMethodList *Method = &Methods.Instance; Method; 1562 Method = Method->Next) 1563 if (Method->Method) 1564 ++NumInstanceMethods; 1565 1566 unsigned NumFactoryMethods = 0; 1567 for (const ObjCMethodList *Method = &Methods.Factory; Method; 1568 Method = Method->Next) 1569 if (Method->Method) 1570 ++NumFactoryMethods; 1571 1572 clang::io::Emit16(Out, NumInstanceMethods); 1573 clang::io::Emit16(Out, NumFactoryMethods); 1574 for (const ObjCMethodList *Method = &Methods.Instance; Method; 1575 Method = Method->Next) 1576 if (Method->Method) 1577 clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 1578 for (const ObjCMethodList *Method = &Methods.Factory; Method; 1579 Method = Method->Next) 1580 if (Method->Method) 1581 clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); 1582 1583 assert(Out.tell() - Start == DataLen && "Data length is wrong"); 1584 } 1585}; 1586} // end anonymous namespace 1587 1588/// \brief Write ObjC data: selectors and the method pool. 1589/// 1590/// The method pool contains both instance and factory methods, stored 1591/// in an on-disk hash table indexed by the selector. The hash table also 1592/// contains an empty entry for every other selector known to Sema. 1593void ASTWriter::WriteSelectors(Sema &SemaRef) { 1594 using namespace llvm; 1595 1596 // Do we have to do anything at all? 1597 if (SemaRef.MethodPool.empty() && SelectorIDs.empty()) 1598 return; 1599 unsigned NumTableEntries = 0; 1600 // Create and write out the blob that contains selectors and the method pool. 1601 { 1602 OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator; 1603 ASTMethodPoolTrait Trait(*this); 1604 1605 // Create the on-disk hash table representation. We walk through every 1606 // selector we've seen and look it up in the method pool. 1607 SelectorOffsets.resize(NextSelectorID - FirstSelectorID); 1608 for (llvm::DenseMap<Selector, SelectorID>::iterator 1609 I = SelectorIDs.begin(), E = SelectorIDs.end(); 1610 I != E; ++I) { 1611 Selector S = I->first; 1612 Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); 1613 ASTMethodPoolTrait::data_type Data = { 1614 I->second, 1615 ObjCMethodList(), 1616 ObjCMethodList() 1617 }; 1618 if (F != SemaRef.MethodPool.end()) { 1619 Data.Instance = F->second.first; 1620 Data.Factory = F->second.second; 1621 } 1622 // Only write this selector if it's not in an existing AST or something 1623 // changed. 1624 if (Chain && I->second < FirstSelectorID) { 1625 // Selector already exists. Did it change? 1626 bool changed = false; 1627 for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method; 1628 M = M->Next) { 1629 if (M->Method->getPCHLevel() == 0) 1630 changed = true; 1631 } 1632 for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method; 1633 M = M->Next) { 1634 if (M->Method->getPCHLevel() == 0) 1635 changed = true; 1636 } 1637 if (!changed) 1638 continue; 1639 } else if (Data.Instance.Method || Data.Factory.Method) { 1640 // A new method pool entry. 1641 ++NumTableEntries; 1642 } 1643 Generator.insert(S, Data, Trait); 1644 } 1645 1646 // Create the on-disk hash table in a buffer. 1647 llvm::SmallString<4096> MethodPool; 1648 uint32_t BucketOffset; 1649 { 1650 ASTMethodPoolTrait Trait(*this); 1651 llvm::raw_svector_ostream Out(MethodPool); 1652 // Make sure that no bucket is at offset 0 1653 clang::io::Emit32(Out, 0); 1654 BucketOffset = Generator.Emit(Out, Trait); 1655 } 1656 1657 // Create a blob abbreviation 1658 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1659 Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL)); 1660 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1661 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1662 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1663 unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev); 1664 1665 // Write the method pool 1666 RecordData Record; 1667 Record.push_back(METHOD_POOL); 1668 Record.push_back(BucketOffset); 1669 Record.push_back(NumTableEntries); 1670 Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str()); 1671 1672 // Create a blob abbreviation for the selector table offsets. 1673 Abbrev = new BitCodeAbbrev(); 1674 Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS)); 1675 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index 1676 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1677 unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1678 1679 // Write the selector offsets table. 1680 Record.clear(); 1681 Record.push_back(SELECTOR_OFFSETS); 1682 Record.push_back(SelectorOffsets.size()); 1683 Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, 1684 (const char *)data(SelectorOffsets), 1685 SelectorOffsets.size() * 4); 1686 } 1687} 1688 1689/// \brief Write the selectors referenced in @selector expression into AST file. 1690void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { 1691 using namespace llvm; 1692 if (SemaRef.ReferencedSelectors.empty()) 1693 return; 1694 1695 RecordData Record; 1696 1697 // Note: this writes out all references even for a dependent AST. But it is 1698 // very tricky to fix, and given that @selector shouldn't really appear in 1699 // headers, probably not worth it. It's not a correctness issue. 1700 for (DenseMap<Selector, SourceLocation>::iterator S = 1701 SemaRef.ReferencedSelectors.begin(), 1702 E = SemaRef.ReferencedSelectors.end(); S != E; ++S) { 1703 Selector Sel = (*S).first; 1704 SourceLocation Loc = (*S).second; 1705 AddSelectorRef(Sel, Record); 1706 AddSourceLocation(Loc, Record); 1707 } 1708 Stream.EmitRecord(REFERENCED_SELECTOR_POOL, Record); 1709} 1710 1711//===----------------------------------------------------------------------===// 1712// Identifier Table Serialization 1713//===----------------------------------------------------------------------===// 1714 1715namespace { 1716class ASTIdentifierTableTrait { 1717 ASTWriter &Writer; 1718 Preprocessor &PP; 1719 1720 /// \brief Determines whether this is an "interesting" identifier 1721 /// that needs a full IdentifierInfo structure written into the hash 1722 /// table. 1723 static bool isInterestingIdentifier(const IdentifierInfo *II) { 1724 return II->isPoisoned() || 1725 II->isExtensionToken() || 1726 II->hasMacroDefinition() || 1727 II->getObjCOrBuiltinID() || 1728 II->getFETokenInfo<void>(); 1729 } 1730 1731public: 1732 typedef const IdentifierInfo* key_type; 1733 typedef key_type key_type_ref; 1734 1735 typedef IdentID data_type; 1736 typedef data_type data_type_ref; 1737 1738 ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP) 1739 : Writer(Writer), PP(PP) { } 1740 1741 static unsigned ComputeHash(const IdentifierInfo* II) { 1742 return llvm::HashString(II->getName()); 1743 } 1744 1745 std::pair<unsigned,unsigned> 1746 EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II, 1747 IdentID ID) { 1748 unsigned KeyLen = II->getLength() + 1; 1749 unsigned DataLen = 4; // 4 bytes for the persistent ID << 1 1750 if (isInterestingIdentifier(II)) { 1751 DataLen += 2; // 2 bytes for builtin ID, flags 1752 if (II->hasMacroDefinition() && 1753 !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro()) 1754 DataLen += 4; 1755 for (IdentifierResolver::iterator D = IdentifierResolver::begin(II), 1756 DEnd = IdentifierResolver::end(); 1757 D != DEnd; ++D) 1758 DataLen += sizeof(DeclID); 1759 } 1760 clang::io::Emit16(Out, DataLen); 1761 // We emit the key length after the data length so that every 1762 // string is preceded by a 16-bit length. This matches the PTH 1763 // format for storing identifiers. 1764 clang::io::Emit16(Out, KeyLen); 1765 return std::make_pair(KeyLen, DataLen); 1766 } 1767 1768 void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II, 1769 unsigned KeyLen) { 1770 // Record the location of the key data. This is used when generating 1771 // the mapping from persistent IDs to strings. 1772 Writer.SetIdentifierOffset(II, Out.tell()); 1773 Out.write(II->getNameStart(), KeyLen); 1774 } 1775 1776 void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II, 1777 IdentID ID, unsigned) { 1778 if (!isInterestingIdentifier(II)) { 1779 clang::io::Emit32(Out, ID << 1); 1780 return; 1781 } 1782 1783 clang::io::Emit32(Out, (ID << 1) | 0x01); 1784 uint32_t Bits = 0; 1785 bool hasMacroDefinition = 1786 II->hasMacroDefinition() && 1787 !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro(); 1788 Bits = (uint32_t)II->getObjCOrBuiltinID(); 1789 Bits = (Bits << 1) | unsigned(hasMacroDefinition); 1790 Bits = (Bits << 1) | unsigned(II->isExtensionToken()); 1791 Bits = (Bits << 1) | unsigned(II->isPoisoned()); 1792 Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier()); 1793 Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword()); 1794 clang::io::Emit16(Out, Bits); 1795 1796 if (hasMacroDefinition) 1797 clang::io::Emit32(Out, Writer.getMacroOffset(II)); 1798 1799 // Emit the declaration IDs in reverse order, because the 1800 // IdentifierResolver provides the declarations as they would be 1801 // visible (e.g., the function "stat" would come before the struct 1802 // "stat"), but IdentifierResolver::AddDeclToIdentifierChain() 1803 // adds declarations to the end of the list (so we need to see the 1804 // struct "status" before the function "status"). 1805 // Only emit declarations that aren't from a chained PCH, though. 1806 llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II), 1807 IdentifierResolver::end()); 1808 for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(), 1809 DEnd = Decls.rend(); 1810 D != DEnd; ++D) 1811 clang::io::Emit32(Out, Writer.getDeclID(*D)); 1812 } 1813}; 1814} // end anonymous namespace 1815 1816/// \brief Write the identifier table into the AST file. 1817/// 1818/// The identifier table consists of a blob containing string data 1819/// (the actual identifiers themselves) and a separate "offsets" index 1820/// that maps identifier IDs to locations within the blob. 1821void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { 1822 using namespace llvm; 1823 1824 // Create and write out the blob that contains the identifier 1825 // strings. 1826 { 1827 OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; 1828 ASTIdentifierTableTrait Trait(*this, PP); 1829 1830 // Look for any identifiers that were named while processing the 1831 // headers, but are otherwise not needed. We add these to the hash 1832 // table to enable checking of the predefines buffer in the case 1833 // where the user adds new macro definitions when building the AST 1834 // file. 1835 for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(), 1836 IDEnd = PP.getIdentifierTable().end(); 1837 ID != IDEnd; ++ID) 1838 getIdentifierRef(ID->second); 1839 1840 // Create the on-disk hash table representation. We only store offsets 1841 // for identifiers that appear here for the first time. 1842 IdentifierOffsets.resize(NextIdentID - FirstIdentID); 1843 for (llvm::DenseMap<const IdentifierInfo *, IdentID>::iterator 1844 ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end(); 1845 ID != IDEnd; ++ID) { 1846 assert(ID->first && "NULL identifier in identifier table"); 1847 if (!Chain || !ID->first->isFromAST()) 1848 Generator.insert(ID->first, ID->second, Trait); 1849 } 1850 1851 // Create the on-disk hash table in a buffer. 1852 llvm::SmallString<4096> IdentifierTable; 1853 uint32_t BucketOffset; 1854 { 1855 ASTIdentifierTableTrait Trait(*this, PP); 1856 llvm::raw_svector_ostream Out(IdentifierTable); 1857 // Make sure that no bucket is at offset 0 1858 clang::io::Emit32(Out, 0); 1859 BucketOffset = Generator.Emit(Out, Trait); 1860 } 1861 1862 // Create a blob abbreviation 1863 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1864 Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE)); 1865 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1866 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1867 unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev); 1868 1869 // Write the identifier table 1870 RecordData Record; 1871 Record.push_back(IDENTIFIER_TABLE); 1872 Record.push_back(BucketOffset); 1873 Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str()); 1874 } 1875 1876 // Write the offsets table for identifier IDs. 1877 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 1878 Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET)); 1879 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers 1880 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1881 unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); 1882 1883 RecordData Record; 1884 Record.push_back(IDENTIFIER_OFFSET); 1885 Record.push_back(IdentifierOffsets.size()); 1886 Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, 1887 (const char *)data(IdentifierOffsets), 1888 IdentifierOffsets.size() * sizeof(uint32_t)); 1889} 1890 1891//===----------------------------------------------------------------------===// 1892// DeclContext's Name Lookup Table Serialization 1893//===----------------------------------------------------------------------===// 1894 1895namespace { 1896// Trait used for the on-disk hash table used in the method pool. 1897class ASTDeclContextNameLookupTrait { 1898 ASTWriter &Writer; 1899 1900public: 1901 typedef DeclarationName key_type; 1902 typedef key_type key_type_ref; 1903 1904 typedef DeclContext::lookup_result data_type; 1905 typedef const data_type& data_type_ref; 1906 1907 explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { } 1908 1909 unsigned ComputeHash(DeclarationName Name) { 1910 llvm::FoldingSetNodeID ID; 1911 ID.AddInteger(Name.getNameKind()); 1912 1913 switch (Name.getNameKind()) { 1914 case DeclarationName::Identifier: 1915 ID.AddString(Name.getAsIdentifierInfo()->getName()); 1916 break; 1917 case DeclarationName::ObjCZeroArgSelector: 1918 case DeclarationName::ObjCOneArgSelector: 1919 case DeclarationName::ObjCMultiArgSelector: 1920 ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector())); 1921 break; 1922 case DeclarationName::CXXConstructorName: 1923 case DeclarationName::CXXDestructorName: 1924 case DeclarationName::CXXConversionFunctionName: 1925 ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType())); 1926 break; 1927 case DeclarationName::CXXOperatorName: 1928 ID.AddInteger(Name.getCXXOverloadedOperator()); 1929 break; 1930 case DeclarationName::CXXLiteralOperatorName: 1931 ID.AddString(Name.getCXXLiteralIdentifier()->getName()); 1932 case DeclarationName::CXXUsingDirective: 1933 break; 1934 } 1935 1936 return ID.ComputeHash(); 1937 } 1938 1939 std::pair<unsigned,unsigned> 1940 EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name, 1941 data_type_ref Lookup) { 1942 unsigned KeyLen = 1; 1943 switch (Name.getNameKind()) { 1944 case DeclarationName::Identifier: 1945 case DeclarationName::ObjCZeroArgSelector: 1946 case DeclarationName::ObjCOneArgSelector: 1947 case DeclarationName::ObjCMultiArgSelector: 1948 case DeclarationName::CXXConstructorName: 1949 case DeclarationName::CXXDestructorName: 1950 case DeclarationName::CXXConversionFunctionName: 1951 case DeclarationName::CXXLiteralOperatorName: 1952 KeyLen += 4; 1953 break; 1954 case DeclarationName::CXXOperatorName: 1955 KeyLen += 1; 1956 break; 1957 case DeclarationName::CXXUsingDirective: 1958 break; 1959 } 1960 clang::io::Emit16(Out, KeyLen); 1961 1962 // 2 bytes for num of decls and 4 for each DeclID. 1963 unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first); 1964 clang::io::Emit16(Out, DataLen); 1965 1966 return std::make_pair(KeyLen, DataLen); 1967 } 1968 1969 void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) { 1970 using namespace clang::io; 1971 1972 assert(Name.getNameKind() < 0x100 && "Invalid name kind ?"); 1973 Emit8(Out, Name.getNameKind()); 1974 switch (Name.getNameKind()) { 1975 case DeclarationName::Identifier: 1976 Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo())); 1977 break; 1978 case DeclarationName::ObjCZeroArgSelector: 1979 case DeclarationName::ObjCOneArgSelector: 1980 case DeclarationName::ObjCMultiArgSelector: 1981 Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector())); 1982 break; 1983 case DeclarationName::CXXConstructorName: 1984 case DeclarationName::CXXDestructorName: 1985 case DeclarationName::CXXConversionFunctionName: 1986 Emit32(Out, Writer.getTypeID(Name.getCXXNameType())); 1987 break; 1988 case DeclarationName::CXXOperatorName: 1989 assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?"); 1990 Emit8(Out, Name.getCXXOverloadedOperator()); 1991 break; 1992 case DeclarationName::CXXLiteralOperatorName: 1993 Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier())); 1994 break; 1995 case DeclarationName::CXXUsingDirective: 1996 break; 1997 } 1998 } 1999 2000 void EmitData(llvm::raw_ostream& Out, key_type_ref, 2001 data_type Lookup, unsigned DataLen) { 2002 uint64_t Start = Out.tell(); (void)Start; 2003 clang::io::Emit16(Out, Lookup.second - Lookup.first); 2004 for (; Lookup.first != Lookup.second; ++Lookup.first) 2005 clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first)); 2006 2007 assert(Out.tell() - Start == DataLen && "Data length is wrong"); 2008 } 2009}; 2010} // end anonymous namespace 2011 2012/// \brief Write the block containing all of the declaration IDs 2013/// visible from the given DeclContext. 2014/// 2015/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the 2016/// bistream, or 0 if no block was written. 2017uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, 2018 DeclContext *DC) { 2019 if (DC->getPrimaryContext() != DC) 2020 return 0; 2021 2022 // Since there is no name lookup into functions or methods, don't bother to 2023 // build a visible-declarations table for these entities. 2024 if (DC->isFunctionOrMethod()) 2025 return 0; 2026 2027 // If not in C++, we perform name lookup for the translation unit via the 2028 // IdentifierInfo chains, don't bother to build a visible-declarations table. 2029 // FIXME: In C++ we need the visible declarations in order to "see" the 2030 // friend declarations, is there a way to do this without writing the table ? 2031 if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) 2032 return 0; 2033 2034 // Force the DeclContext to build a its name-lookup table. 2035 DC->lookup(DeclarationName()); 2036 2037 // Serialize the contents of the mapping used for lookup. Note that, 2038 // although we have two very different code paths, the serialized 2039 // representation is the same for both cases: a declaration name, 2040 // followed by a size, followed by references to the visible 2041 // declarations that have that name. 2042 uint64_t Offset = Stream.GetCurrentBitNo(); 2043 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); 2044 if (!Map || Map->empty()) 2045 return 0; 2046 2047 OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; 2048 ASTDeclContextNameLookupTrait Trait(*this); 2049 2050 // Create the on-disk hash table representation. 2051 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); 2052 D != DEnd; ++D) { 2053 DeclarationName Name = D->first; 2054 DeclContext::lookup_result Result = D->second.getLookupResult(); 2055 Generator.insert(Name, Result, Trait); 2056 } 2057 2058 // Create the on-disk hash table in a buffer. 2059 llvm::SmallString<4096> LookupTable; 2060 uint32_t BucketOffset; 2061 { 2062 llvm::raw_svector_ostream Out(LookupTable); 2063 // Make sure that no bucket is at offset 0 2064 clang::io::Emit32(Out, 0); 2065 BucketOffset = Generator.Emit(Out, Trait); 2066 } 2067 2068 // Write the lookup table 2069 RecordData Record; 2070 Record.push_back(DECL_CONTEXT_VISIBLE); 2071 Record.push_back(BucketOffset); 2072 Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, 2073 LookupTable.str()); 2074 2075 Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); 2076 ++NumVisibleDeclContexts; 2077 return Offset; 2078} 2079 2080//===----------------------------------------------------------------------===// 2081// General Serialization Routines 2082//===----------------------------------------------------------------------===// 2083 2084/// \brief Write a record containing the given attributes. 2085void ASTWriter::WriteAttributeRecord(const AttrVec &Attrs) { 2086 RecordData Record; 2087 for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){ 2088 const Attr * A = *i; 2089 Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs 2090 AddSourceLocation(A->getLocation(), Record); 2091 Record.push_back(A->isInherited()); 2092 2093#include "clang/Serialization/AttrPCHWrite.inc" 2094 2095 } 2096 2097 Stream.EmitRecord(DECL_ATTR, Record); 2098} 2099 2100void ASTWriter::AddString(const std::string &Str, RecordData &Record) { 2101 Record.push_back(Str.size()); 2102 Record.insert(Record.end(), Str.begin(), Str.end()); 2103} 2104 2105/// \brief Note that the identifier II occurs at the given offset 2106/// within the identifier table. 2107void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { 2108 IdentID ID = IdentifierIDs[II]; 2109 // Only store offsets new to this AST file. Other identifier names are looked 2110 // up earlier in the chain and thus don't need an offset. 2111 if (ID >= FirstIdentID) 2112 IdentifierOffsets[ID - FirstIdentID] = Offset; 2113} 2114 2115/// \brief Note that the selector Sel occurs at the given offset 2116/// within the method pool/selector table. 2117void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { 2118 unsigned ID = SelectorIDs[Sel]; 2119 assert(ID && "Unknown selector"); 2120 // Don't record offsets for selectors that are also available in a different 2121 // file. 2122 if (ID < FirstSelectorID) 2123 return; 2124 SelectorOffsets[ID - FirstSelectorID] = Offset; 2125} 2126 2127ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) 2128 : Stream(Stream), Chain(0), FirstDeclID(1), NextDeclID(FirstDeclID), 2129 FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), 2130 FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), 2131 NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit), 2132 NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), 2133 NumVisibleDeclContexts(0) { 2134} 2135 2136void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2137 const char *isysroot) { 2138 // Emit the file header. 2139 Stream.Emit((unsigned)'C', 8); 2140 Stream.Emit((unsigned)'P', 8); 2141 Stream.Emit((unsigned)'C', 8); 2142 Stream.Emit((unsigned)'H', 8); 2143 2144 WriteBlockInfoBlock(); 2145 2146 if (Chain) 2147 WriteASTChain(SemaRef, StatCalls, isysroot); 2148 else 2149 WriteASTCore(SemaRef, StatCalls, isysroot); 2150} 2151 2152void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2153 const char *isysroot) { 2154 using namespace llvm; 2155 2156 ASTContext &Context = SemaRef.Context; 2157 Preprocessor &PP = SemaRef.PP; 2158 2159 // The translation unit is the first declaration we'll emit. 2160 DeclIDs[Context.getTranslationUnitDecl()] = 1; 2161 ++NextDeclID; 2162 DeclTypesToEmit.push(Context.getTranslationUnitDecl()); 2163 2164 // Make sure that we emit IdentifierInfos (and any attached 2165 // declarations) for builtins. 2166 { 2167 IdentifierTable &Table = PP.getIdentifierTable(); 2168 llvm::SmallVector<const char *, 32> BuiltinNames; 2169 Context.BuiltinInfo.GetBuiltinNames(BuiltinNames, 2170 Context.getLangOptions().NoBuiltin); 2171 for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I) 2172 getIdentifierRef(&Table.get(BuiltinNames[I])); 2173 } 2174 2175 // Build a record containing all of the tentative definitions in this file, in 2176 // TentativeDefinitions order. Generally, this record will be empty for 2177 // headers. 2178 RecordData TentativeDefinitions; 2179 for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 2180 AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 2181 } 2182 2183 // Build a record containing all of the file scoped decls in this file. 2184 RecordData UnusedFileScopedDecls; 2185 for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) 2186 AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 2187 2188 RecordData WeakUndeclaredIdentifiers; 2189 if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 2190 WeakUndeclaredIdentifiers.push_back( 2191 SemaRef.WeakUndeclaredIdentifiers.size()); 2192 for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 2193 I = SemaRef.WeakUndeclaredIdentifiers.begin(), 2194 E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 2195 AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 2196 AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 2197 AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 2198 WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 2199 } 2200 } 2201 2202 // Build a record containing all of the locally-scoped external 2203 // declarations in this header file. Generally, this record will be 2204 // empty. 2205 RecordData LocallyScopedExternalDecls; 2206 // FIXME: This is filling in the AST file in densemap order which is 2207 // nondeterminstic! 2208 for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 2209 TD = SemaRef.LocallyScopedExternalDecls.begin(), 2210 TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 2211 TD != TDEnd; ++TD) 2212 AddDeclRef(TD->second, LocallyScopedExternalDecls); 2213 2214 // Build a record containing all of the ext_vector declarations. 2215 RecordData ExtVectorDecls; 2216 for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) 2217 AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 2218 2219 // Build a record containing all of the VTable uses information. 2220 RecordData VTableUses; 2221 if (!SemaRef.VTableUses.empty()) { 2222 VTableUses.push_back(SemaRef.VTableUses.size()); 2223 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 2224 AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 2225 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 2226 VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 2227 } 2228 } 2229 2230 // Build a record containing all of dynamic classes declarations. 2231 RecordData DynamicClasses; 2232 for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 2233 AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 2234 2235 // Build a record containing all of pending implicit instantiations. 2236 RecordData PendingImplicitInstantiations; 2237 for (std::deque<Sema::PendingImplicitInstantiation>::iterator 2238 I = SemaRef.PendingImplicitInstantiations.begin(), 2239 N = SemaRef.PendingImplicitInstantiations.end(); I != N; ++I) { 2240 AddDeclRef(I->first, PendingImplicitInstantiations); 2241 AddSourceLocation(I->second, PendingImplicitInstantiations); 2242 } 2243 assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 2244 "There are local ones at end of translation unit!"); 2245 2246 // Build a record containing some declaration references. 2247 RecordData SemaDeclRefs; 2248 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 2249 AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 2250 AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 2251 } 2252 2253 // Write the remaining AST contents. 2254 RecordData Record; 2255 Stream.EnterSubblock(AST_BLOCK_ID, 5); 2256 WriteMetadata(Context, isysroot); 2257 WriteLanguageOptions(Context.getLangOptions()); 2258 if (StatCalls && !isysroot) 2259 WriteStatCache(*StatCalls); 2260 WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2261 // Write the record of special types. 2262 Record.clear(); 2263 2264 AddTypeRef(Context.getBuiltinVaListType(), Record); 2265 AddTypeRef(Context.getObjCIdType(), Record); 2266 AddTypeRef(Context.getObjCSelType(), Record); 2267 AddTypeRef(Context.getObjCProtoType(), Record); 2268 AddTypeRef(Context.getObjCClassType(), Record); 2269 AddTypeRef(Context.getRawCFConstantStringType(), Record); 2270 AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record); 2271 AddTypeRef(Context.getFILEType(), Record); 2272 AddTypeRef(Context.getjmp_bufType(), Record); 2273 AddTypeRef(Context.getsigjmp_bufType(), Record); 2274 AddTypeRef(Context.ObjCIdRedefinitionType, Record); 2275 AddTypeRef(Context.ObjCClassRedefinitionType, Record); 2276 AddTypeRef(Context.getRawBlockdescriptorType(), Record); 2277 AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record); 2278 AddTypeRef(Context.ObjCSelRedefinitionType, Record); 2279 AddTypeRef(Context.getRawNSConstantStringType(), Record); 2280 Record.push_back(Context.isInt128Installed()); 2281 Stream.EmitRecord(SPECIAL_TYPES, Record); 2282 2283 // Keep writing types and declarations until all types and 2284 // declarations have been written. 2285 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3); 2286 WriteDeclsBlockAbbrevs(); 2287 while (!DeclTypesToEmit.empty()) { 2288 DeclOrType DOT = DeclTypesToEmit.front(); 2289 DeclTypesToEmit.pop(); 2290 if (DOT.isType()) 2291 WriteType(DOT.getType()); 2292 else 2293 WriteDecl(Context, DOT.getDecl()); 2294 } 2295 Stream.ExitBlock(); 2296 2297 WritePreprocessor(PP); 2298 WriteSelectors(SemaRef); 2299 WriteReferencedSelectorsPool(SemaRef); 2300 WriteIdentifierTable(PP); 2301 2302 WriteTypeDeclOffsets(); 2303 2304 // Write the record containing external, unnamed definitions. 2305 if (!ExternalDefinitions.empty()) 2306 Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 2307 2308 // Write the record containing tentative definitions. 2309 if (!TentativeDefinitions.empty()) 2310 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 2311 2312 // Write the record containing unused file scoped decls. 2313 if (!UnusedFileScopedDecls.empty()) 2314 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 2315 2316 // Write the record containing weak undeclared identifiers. 2317 if (!WeakUndeclaredIdentifiers.empty()) 2318 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 2319 WeakUndeclaredIdentifiers); 2320 2321 // Write the record containing locally-scoped external definitions. 2322 if (!LocallyScopedExternalDecls.empty()) 2323 Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 2324 LocallyScopedExternalDecls); 2325 2326 // Write the record containing ext_vector type names. 2327 if (!ExtVectorDecls.empty()) 2328 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 2329 2330 // Write the record containing VTable uses information. 2331 if (!VTableUses.empty()) 2332 Stream.EmitRecord(VTABLE_USES, VTableUses); 2333 2334 // Write the record containing dynamic classes declarations. 2335 if (!DynamicClasses.empty()) 2336 Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 2337 2338 // Write the record containing pending implicit instantiations. 2339 if (!PendingImplicitInstantiations.empty()) 2340 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, 2341 PendingImplicitInstantiations); 2342 2343 // Write the record containing declaration references of Sema. 2344 if (!SemaDeclRefs.empty()) 2345 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 2346 2347 // Some simple statistics 2348 Record.clear(); 2349 Record.push_back(NumStatements); 2350 Record.push_back(NumMacros); 2351 Record.push_back(NumLexicalDeclContexts); 2352 Record.push_back(NumVisibleDeclContexts); 2353 Stream.EmitRecord(STATISTICS, Record); 2354 Stream.ExitBlock(); 2355} 2356 2357void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, 2358 const char *isysroot) { 2359 using namespace llvm; 2360 2361 FirstDeclID += Chain->getTotalNumDecls(); 2362 FirstTypeID += Chain->getTotalNumTypes(); 2363 FirstIdentID += Chain->getTotalNumIdentifiers(); 2364 FirstSelectorID += Chain->getTotalNumSelectors(); 2365 NextDeclID = FirstDeclID; 2366 NextTypeID = FirstTypeID; 2367 NextIdentID = FirstIdentID; 2368 NextSelectorID = FirstSelectorID; 2369 2370 ASTContext &Context = SemaRef.Context; 2371 Preprocessor &PP = SemaRef.PP; 2372 2373 RecordData Record; 2374 Stream.EnterSubblock(AST_BLOCK_ID, 5); 2375 WriteMetadata(Context, isysroot); 2376 if (StatCalls && !isysroot) 2377 WriteStatCache(*StatCalls); 2378 // FIXME: Source manager block should only write new stuff, which could be 2379 // done by tracking the largest ID in the chain 2380 WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); 2381 2382 // The special types are in the chained PCH. 2383 2384 // We don't start with the translation unit, but with its decls that 2385 // don't come from the chained PCH. 2386 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); 2387 llvm::SmallVector<DeclID, 64> NewGlobalDecls; 2388 for (DeclContext::decl_iterator I = TU->noload_decls_begin(), 2389 E = TU->noload_decls_end(); 2390 I != E; ++I) { 2391 if ((*I)->getPCHLevel() == 0) 2392 NewGlobalDecls.push_back(GetDeclRef(*I)); 2393 else if ((*I)->isChangedSinceDeserialization()) 2394 (void)GetDeclRef(*I); // Make sure it's written, but don't record it. 2395 } 2396 // We also need to write a lexical updates block for the TU. 2397 llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev(); 2398 Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); 2399 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 2400 unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abv); 2401 Record.clear(); 2402 Record.push_back(TU_UPDATE_LEXICAL); 2403 Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, 2404 reinterpret_cast<const char*>(NewGlobalDecls.data()), 2405 NewGlobalDecls.size() * sizeof(DeclID)); 2406 2407 // Build a record containing all of the new tentative definitions in this 2408 // file, in TentativeDefinitions order. 2409 RecordData TentativeDefinitions; 2410 for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) { 2411 if (SemaRef.TentativeDefinitions[i]->getPCHLevel() == 0) 2412 AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); 2413 } 2414 2415 // Build a record containing all of the file scoped decls in this file. 2416 RecordData UnusedFileScopedDecls; 2417 for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) { 2418 if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0) 2419 AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); 2420 } 2421 2422 // We write the entire table, overwriting the tables from the chain. 2423 RecordData WeakUndeclaredIdentifiers; 2424 if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { 2425 WeakUndeclaredIdentifiers.push_back( 2426 SemaRef.WeakUndeclaredIdentifiers.size()); 2427 for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator 2428 I = SemaRef.WeakUndeclaredIdentifiers.begin(), 2429 E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { 2430 AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); 2431 AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); 2432 AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); 2433 WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); 2434 } 2435 } 2436 2437 // Build a record containing all of the locally-scoped external 2438 // declarations in this header file. Generally, this record will be 2439 // empty. 2440 RecordData LocallyScopedExternalDecls; 2441 // FIXME: This is filling in the AST file in densemap order which is 2442 // nondeterminstic! 2443 for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 2444 TD = SemaRef.LocallyScopedExternalDecls.begin(), 2445 TDEnd = SemaRef.LocallyScopedExternalDecls.end(); 2446 TD != TDEnd; ++TD) { 2447 if (TD->second->getPCHLevel() == 0) 2448 AddDeclRef(TD->second, LocallyScopedExternalDecls); 2449 } 2450 2451 // Build a record containing all of the ext_vector declarations. 2452 RecordData ExtVectorDecls; 2453 for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) { 2454 if (SemaRef.ExtVectorDecls[I]->getPCHLevel() == 0) 2455 AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); 2456 } 2457 2458 // Build a record containing all of the VTable uses information. 2459 // We write everything here, because it's too hard to determine whether 2460 // a use is new to this part. 2461 RecordData VTableUses; 2462 if (!SemaRef.VTableUses.empty()) { 2463 VTableUses.push_back(SemaRef.VTableUses.size()); 2464 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 2465 AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 2466 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 2467 VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 2468 } 2469 } 2470 2471 // Build a record containing all of dynamic classes declarations. 2472 RecordData DynamicClasses; 2473 for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) 2474 if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0) 2475 AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); 2476 2477 // Build a record containing all of pending implicit instantiations. 2478 RecordData PendingImplicitInstantiations; 2479 for (std::deque<Sema::PendingImplicitInstantiation>::iterator 2480 I = SemaRef.PendingImplicitInstantiations.begin(), 2481 N = SemaRef.PendingImplicitInstantiations.end(); I != N; ++I) { 2482 if (I->first->getPCHLevel() == 0) { 2483 AddDeclRef(I->first, PendingImplicitInstantiations); 2484 AddSourceLocation(I->second, PendingImplicitInstantiations); 2485 } 2486 } 2487 assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 2488 "There are local ones at end of translation unit!"); 2489 2490 // Build a record containing some declaration references. 2491 // It's not worth the effort to avoid duplication here. 2492 RecordData SemaDeclRefs; 2493 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { 2494 AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 2495 AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 2496 } 2497 2498 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3); 2499 WriteDeclsBlockAbbrevs(); 2500 while (!DeclTypesToEmit.empty()) { 2501 DeclOrType DOT = DeclTypesToEmit.front(); 2502 DeclTypesToEmit.pop(); 2503 if (DOT.isType()) 2504 WriteType(DOT.getType()); 2505 else 2506 WriteDecl(Context, DOT.getDecl()); 2507 } 2508 Stream.ExitBlock(); 2509 2510 WritePreprocessor(PP); 2511 WriteSelectors(SemaRef); 2512 WriteReferencedSelectorsPool(SemaRef); 2513 WriteIdentifierTable(PP); 2514 WriteTypeDeclOffsets(); 2515 2516 /// Build a record containing first declarations from a chained PCH and the 2517 /// most recent declarations in this AST that they point to. 2518 RecordData FirstLatestDeclIDs; 2519 for (FirstLatestDeclMap::iterator 2520 I = FirstLatestDecls.begin(), E = FirstLatestDecls.end(); I != E; ++I) { 2521 assert(I->first->getPCHLevel() > I->second->getPCHLevel() && 2522 "Expected first & second to be in different PCHs"); 2523 AddDeclRef(I->first, FirstLatestDeclIDs); 2524 AddDeclRef(I->second, FirstLatestDeclIDs); 2525 } 2526 if (!FirstLatestDeclIDs.empty()) 2527 Stream.EmitRecord(REDECLS_UPDATE_LATEST, FirstLatestDeclIDs); 2528 2529 // Write the record containing external, unnamed definitions. 2530 if (!ExternalDefinitions.empty()) 2531 Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); 2532 2533 // Write the record containing tentative definitions. 2534 if (!TentativeDefinitions.empty()) 2535 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 2536 2537 // Write the record containing unused file scoped decls. 2538 if (!UnusedFileScopedDecls.empty()) 2539 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 2540 2541 // Write the record containing weak undeclared identifiers. 2542 if (!WeakUndeclaredIdentifiers.empty()) 2543 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 2544 WeakUndeclaredIdentifiers); 2545 2546 // Write the record containing locally-scoped external definitions. 2547 if (!LocallyScopedExternalDecls.empty()) 2548 Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS, 2549 LocallyScopedExternalDecls); 2550 2551 // Write the record containing ext_vector type names. 2552 if (!ExtVectorDecls.empty()) 2553 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 2554 2555 // Write the record containing VTable uses information. 2556 if (!VTableUses.empty()) 2557 Stream.EmitRecord(VTABLE_USES, VTableUses); 2558 2559 // Write the record containing dynamic classes declarations. 2560 if (!DynamicClasses.empty()) 2561 Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); 2562 2563 // Write the record containing pending implicit instantiations. 2564 if (!PendingImplicitInstantiations.empty()) 2565 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, 2566 PendingImplicitInstantiations); 2567 2568 // Write the record containing declaration references of Sema. 2569 if (!SemaDeclRefs.empty()) 2570 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 2571 2572 Record.clear(); 2573 Record.push_back(NumStatements); 2574 Record.push_back(NumMacros); 2575 Record.push_back(NumLexicalDeclContexts); 2576 Record.push_back(NumVisibleDeclContexts); 2577 WriteDeclUpdateBlock(); 2578 Stream.EmitRecord(STATISTICS, Record); 2579 Stream.ExitBlock(); 2580} 2581 2582void ASTWriter::WriteDeclUpdateBlock() { 2583 if (ReplacedDecls.empty()) 2584 return; 2585 2586 RecordData Record; 2587 for (llvm::SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator 2588 I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) { 2589 Record.push_back(I->first); 2590 Record.push_back(I->second); 2591 } 2592 Stream.EmitRecord(DECL_REPLACEMENTS, Record); 2593} 2594 2595void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) { 2596 Record.push_back(Loc.getRawEncoding()); 2597} 2598 2599void ASTWriter::AddSourceRange(SourceRange Range, RecordData &Record) { 2600 AddSourceLocation(Range.getBegin(), Record); 2601 AddSourceLocation(Range.getEnd(), Record); 2602} 2603 2604void ASTWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) { 2605 Record.push_back(Value.getBitWidth()); 2606 unsigned N = Value.getNumWords(); 2607 const uint64_t* Words = Value.getRawData(); 2608 for (unsigned I = 0; I != N; ++I) 2609 Record.push_back(Words[I]); 2610} 2611 2612void ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) { 2613 Record.push_back(Value.isUnsigned()); 2614 AddAPInt(Value, Record); 2615} 2616 2617void ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordData &Record) { 2618 AddAPInt(Value.bitcastToAPInt(), Record); 2619} 2620 2621void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) { 2622 Record.push_back(getIdentifierRef(II)); 2623} 2624 2625IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) { 2626 if (II == 0) 2627 return 0; 2628 2629 IdentID &ID = IdentifierIDs[II]; 2630 if (ID == 0) 2631 ID = NextIdentID++; 2632 return ID; 2633} 2634 2635IdentID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) { 2636 if (MD == 0) 2637 return 0; 2638 2639 IdentID &ID = MacroDefinitions[MD]; 2640 if (ID == 0) 2641 ID = MacroDefinitions.size(); 2642 return ID; 2643} 2644 2645void ASTWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) { 2646 Record.push_back(getSelectorRef(SelRef)); 2647} 2648 2649SelectorID ASTWriter::getSelectorRef(Selector Sel) { 2650 if (Sel.getAsOpaquePtr() == 0) { 2651 return 0; 2652 } 2653 2654 SelectorID &SID = SelectorIDs[Sel]; 2655 if (SID == 0 && Chain) { 2656 // This might trigger a ReadSelector callback, which will set the ID for 2657 // this selector. 2658 Chain->LoadSelector(Sel); 2659 } 2660 if (SID == 0) { 2661 SID = NextSelectorID++; 2662 } 2663 return SID; 2664} 2665 2666void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record) { 2667 AddDeclRef(Temp->getDestructor(), Record); 2668} 2669 2670void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, 2671 const TemplateArgumentLocInfo &Arg, 2672 RecordData &Record) { 2673 switch (Kind) { 2674 case TemplateArgument::Expression: 2675 AddStmt(Arg.getAsExpr()); 2676 break; 2677 case TemplateArgument::Type: 2678 AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record); 2679 break; 2680 case TemplateArgument::Template: 2681 AddSourceRange(Arg.getTemplateQualifierRange(), Record); 2682 AddSourceLocation(Arg.getTemplateNameLoc(), Record); 2683 break; 2684 case TemplateArgument::Null: 2685 case TemplateArgument::Integral: 2686 case TemplateArgument::Declaration: 2687 case TemplateArgument::Pack: 2688 break; 2689 } 2690} 2691 2692void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, 2693 RecordData &Record) { 2694 AddTemplateArgument(Arg.getArgument(), Record); 2695 2696 if (Arg.getArgument().getKind() == TemplateArgument::Expression) { 2697 bool InfoHasSameExpr 2698 = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr(); 2699 Record.push_back(InfoHasSameExpr); 2700 if (InfoHasSameExpr) 2701 return; // Avoid storing the same expr twice. 2702 } 2703 AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(), 2704 Record); 2705} 2706 2707void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record) { 2708 if (TInfo == 0) { 2709 AddTypeRef(QualType(), Record); 2710 return; 2711 } 2712 2713 AddTypeRef(TInfo->getType(), Record); 2714 TypeLocWriter TLW(*this, Record); 2715 for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) 2716 TLW.Visit(TL); 2717} 2718 2719void ASTWriter::AddTypeRef(QualType T, RecordData &Record) { 2720 Record.push_back(GetOrCreateTypeID(T)); 2721} 2722 2723TypeID ASTWriter::GetOrCreateTypeID(QualType T) { 2724 return MakeTypeID(T, 2725 std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this)); 2726} 2727 2728TypeID ASTWriter::getTypeID(QualType T) const { 2729 return MakeTypeID(T, 2730 std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this)); 2731} 2732 2733TypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) { 2734 if (T.isNull()) 2735 return TypeIdx(); 2736 assert(!T.getLocalFastQualifiers()); 2737 2738 TypeIdx &Idx = TypeIdxs[T]; 2739 if (Idx.getIndex() == 0) { 2740 // We haven't seen this type before. Assign it a new ID and put it 2741 // into the queue of types to emit. 2742 Idx = TypeIdx(NextTypeID++); 2743 DeclTypesToEmit.push(T); 2744 } 2745 return Idx; 2746} 2747 2748TypeIdx ASTWriter::getTypeIdx(QualType T) const { 2749 if (T.isNull()) 2750 return TypeIdx(); 2751 assert(!T.getLocalFastQualifiers()); 2752 2753 TypeIdxMap::const_iterator I = TypeIdxs.find(T); 2754 assert(I != TypeIdxs.end() && "Type not emitted!"); 2755 return I->second; 2756} 2757 2758void ASTWriter::AddDeclRef(const Decl *D, RecordData &Record) { 2759 Record.push_back(GetDeclRef(D)); 2760} 2761 2762DeclID ASTWriter::GetDeclRef(const Decl *D) { 2763 if (D == 0) { 2764 return 0; 2765 } 2766 2767 DeclID &ID = DeclIDs[D]; 2768 if (ID == 0) { 2769 // We haven't seen this declaration before. Give it a new ID and 2770 // enqueue it in the list of declarations to emit. 2771 ID = NextDeclID++; 2772 DeclTypesToEmit.push(const_cast<Decl *>(D)); 2773 } else if (ID < FirstDeclID && D->isChangedSinceDeserialization()) { 2774 // We don't add it to the replacement collection here, because we don't 2775 // have the offset yet. 2776 DeclTypesToEmit.push(const_cast<Decl *>(D)); 2777 // Reset the flag, so that we don't add this decl multiple times. 2778 const_cast<Decl *>(D)->setChangedSinceDeserialization(false); 2779 } 2780 2781 return ID; 2782} 2783 2784DeclID ASTWriter::getDeclID(const Decl *D) { 2785 if (D == 0) 2786 return 0; 2787 2788 assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!"); 2789 return DeclIDs[D]; 2790} 2791 2792void ASTWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) { 2793 // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc. 2794 Record.push_back(Name.getNameKind()); 2795 switch (Name.getNameKind()) { 2796 case DeclarationName::Identifier: 2797 AddIdentifierRef(Name.getAsIdentifierInfo(), Record); 2798 break; 2799 2800 case DeclarationName::ObjCZeroArgSelector: 2801 case DeclarationName::ObjCOneArgSelector: 2802 case DeclarationName::ObjCMultiArgSelector: 2803 AddSelectorRef(Name.getObjCSelector(), Record); 2804 break; 2805 2806 case DeclarationName::CXXConstructorName: 2807 case DeclarationName::CXXDestructorName: 2808 case DeclarationName::CXXConversionFunctionName: 2809 AddTypeRef(Name.getCXXNameType(), Record); 2810 break; 2811 2812 case DeclarationName::CXXOperatorName: 2813 Record.push_back(Name.getCXXOverloadedOperator()); 2814 break; 2815 2816 case DeclarationName::CXXLiteralOperatorName: 2817 AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record); 2818 break; 2819 2820 case DeclarationName::CXXUsingDirective: 2821 // No extra data to emit 2822 break; 2823 } 2824} 2825 2826void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, 2827 RecordData &Record) { 2828 // Nested name specifiers usually aren't too long. I think that 8 would 2829 // typically accomodate the vast majority. 2830 llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames; 2831 2832 // Push each of the NNS's onto a stack for serialization in reverse order. 2833 while (NNS) { 2834 NestedNames.push_back(NNS); 2835 NNS = NNS->getPrefix(); 2836 } 2837 2838 Record.push_back(NestedNames.size()); 2839 while(!NestedNames.empty()) { 2840 NNS = NestedNames.pop_back_val(); 2841 NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); 2842 Record.push_back(Kind); 2843 switch (Kind) { 2844 case NestedNameSpecifier::Identifier: 2845 AddIdentifierRef(NNS->getAsIdentifier(), Record); 2846 break; 2847 2848 case NestedNameSpecifier::Namespace: 2849 AddDeclRef(NNS->getAsNamespace(), Record); 2850 break; 2851 2852 case NestedNameSpecifier::TypeSpec: 2853 case NestedNameSpecifier::TypeSpecWithTemplate: 2854 AddTypeRef(QualType(NNS->getAsType(), 0), Record); 2855 Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); 2856 break; 2857 2858 case NestedNameSpecifier::Global: 2859 // Don't need to write an associated value. 2860 break; 2861 } 2862 } 2863} 2864 2865void ASTWriter::AddTemplateName(TemplateName Name, RecordData &Record) { 2866 TemplateName::NameKind Kind = Name.getKind(); 2867 Record.push_back(Kind); 2868 switch (Kind) { 2869 case TemplateName::Template: 2870 AddDeclRef(Name.getAsTemplateDecl(), Record); 2871 break; 2872 2873 case TemplateName::OverloadedTemplate: { 2874 OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate(); 2875 Record.push_back(OvT->size()); 2876 for (OverloadedTemplateStorage::iterator I = OvT->begin(), E = OvT->end(); 2877 I != E; ++I) 2878 AddDeclRef(*I, Record); 2879 break; 2880 } 2881 2882 case TemplateName::QualifiedTemplate: { 2883 QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); 2884 AddNestedNameSpecifier(QualT->getQualifier(), Record); 2885 Record.push_back(QualT->hasTemplateKeyword()); 2886 AddDeclRef(QualT->getTemplateDecl(), Record); 2887 break; 2888 } 2889 2890 case TemplateName::DependentTemplate: { 2891 DependentTemplateName *DepT = Name.getAsDependentTemplateName(); 2892 AddNestedNameSpecifier(DepT->getQualifier(), Record); 2893 Record.push_back(DepT->isIdentifier()); 2894 if (DepT->isIdentifier()) 2895 AddIdentifierRef(DepT->getIdentifier(), Record); 2896 else 2897 Record.push_back(DepT->getOperator()); 2898 break; 2899 } 2900 } 2901} 2902 2903void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, 2904 RecordData &Record) { 2905 Record.push_back(Arg.getKind()); 2906 switch (Arg.getKind()) { 2907 case TemplateArgument::Null: 2908 break; 2909 case TemplateArgument::Type: 2910 AddTypeRef(Arg.getAsType(), Record); 2911 break; 2912 case TemplateArgument::Declaration: 2913 AddDeclRef(Arg.getAsDecl(), Record); 2914 break; 2915 case TemplateArgument::Integral: 2916 AddAPSInt(*Arg.getAsIntegral(), Record); 2917 AddTypeRef(Arg.getIntegralType(), Record); 2918 break; 2919 case TemplateArgument::Template: 2920 AddTemplateName(Arg.getAsTemplate(), Record); 2921 break; 2922 case TemplateArgument::Expression: 2923 AddStmt(Arg.getAsExpr()); 2924 break; 2925 case TemplateArgument::Pack: 2926 Record.push_back(Arg.pack_size()); 2927 for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end(); 2928 I != E; ++I) 2929 AddTemplateArgument(*I, Record); 2930 break; 2931 } 2932} 2933 2934void 2935ASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams, 2936 RecordData &Record) { 2937 assert(TemplateParams && "No TemplateParams!"); 2938 AddSourceLocation(TemplateParams->getTemplateLoc(), Record); 2939 AddSourceLocation(TemplateParams->getLAngleLoc(), Record); 2940 AddSourceLocation(TemplateParams->getRAngleLoc(), Record); 2941 Record.push_back(TemplateParams->size()); 2942 for (TemplateParameterList::const_iterator 2943 P = TemplateParams->begin(), PEnd = TemplateParams->end(); 2944 P != PEnd; ++P) 2945 AddDeclRef(*P, Record); 2946} 2947 2948/// \brief Emit a template argument list. 2949void 2950ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, 2951 RecordData &Record) { 2952 assert(TemplateArgs && "No TemplateArgs!"); 2953 Record.push_back(TemplateArgs->flat_size()); 2954 for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i) 2955 AddTemplateArgument(TemplateArgs->get(i), Record); 2956} 2957 2958 2959void 2960ASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record) { 2961 Record.push_back(Set.size()); 2962 for (UnresolvedSetImpl::const_iterator 2963 I = Set.begin(), E = Set.end(); I != E; ++I) { 2964 AddDeclRef(I.getDecl(), Record); 2965 Record.push_back(I.getAccess()); 2966 } 2967} 2968 2969void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, 2970 RecordData &Record) { 2971 Record.push_back(Base.isVirtual()); 2972 Record.push_back(Base.isBaseOfClass()); 2973 Record.push_back(Base.getAccessSpecifierAsWritten()); 2974 AddTypeSourceInfo(Base.getTypeSourceInfo(), Record); 2975 AddSourceRange(Base.getSourceRange(), Record); 2976} 2977 2978void ASTWriter::AddCXXBaseOrMemberInitializers( 2979 const CXXBaseOrMemberInitializer * const *BaseOrMembers, 2980 unsigned NumBaseOrMembers, RecordData &Record) { 2981 Record.push_back(NumBaseOrMembers); 2982 for (unsigned i=0; i != NumBaseOrMembers; ++i) { 2983 const CXXBaseOrMemberInitializer *Init = BaseOrMembers[i]; 2984 2985 Record.push_back(Init->isBaseInitializer()); 2986 if (Init->isBaseInitializer()) { 2987 AddTypeSourceInfo(Init->getBaseClassInfo(), Record); 2988 Record.push_back(Init->isBaseVirtual()); 2989 } else { 2990 AddDeclRef(Init->getMember(), Record); 2991 } 2992 AddSourceLocation(Init->getMemberLocation(), Record); 2993 AddStmt(Init->getInit()); 2994 AddDeclRef(Init->getAnonUnionMember(), Record); 2995 AddSourceLocation(Init->getLParenLoc(), Record); 2996 AddSourceLocation(Init->getRParenLoc(), Record); 2997 Record.push_back(Init->isWritten()); 2998 if (Init->isWritten()) { 2999 Record.push_back(Init->getSourceOrder()); 3000 } else { 3001 Record.push_back(Init->getNumArrayIndices()); 3002 for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i) 3003 AddDeclRef(Init->getArrayIndex(i), Record); 3004 } 3005 } 3006} 3007 3008void ASTWriter::SetReader(ASTReader *Reader) { 3009 assert(Reader && "Cannot remove chain"); 3010 assert(FirstDeclID == NextDeclID && 3011 FirstTypeID == NextTypeID && 3012 FirstIdentID == NextIdentID && 3013 FirstSelectorID == NextSelectorID && 3014 "Setting chain after writing has started."); 3015 Chain = Reader; 3016} 3017 3018void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) { 3019 IdentifierIDs[II] = ID; 3020} 3021 3022void ASTWriter::TypeRead(TypeIdx Idx, QualType T) { 3023 TypeIdxs[T] = Idx; 3024} 3025 3026void ASTWriter::DeclRead(DeclID ID, const Decl *D) { 3027 DeclIDs[D] = ID; 3028} 3029 3030void ASTWriter::SelectorRead(SelectorID ID, Selector S) { 3031 SelectorIDs[S] = ID; 3032} 3033