1 1.1 joerg //===- ASTWriter.cpp - AST File Writer ------------------------------------===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg // 9 1.1 joerg // This file defines the ASTWriter class, which writes AST files. 10 1.1 joerg // 11 1.1 joerg //===----------------------------------------------------------------------===// 12 1.1 joerg 13 1.1 joerg #include "ASTCommon.h" 14 1.1 joerg #include "ASTReaderInternals.h" 15 1.1 joerg #include "MultiOnDiskHashTable.h" 16 1.1 joerg #include "clang/AST/ASTContext.h" 17 1.1 joerg #include "clang/AST/ASTUnresolvedSet.h" 18 1.1.1.2 joerg #include "clang/AST/AbstractTypeWriter.h" 19 1.1 joerg #include "clang/AST/Attr.h" 20 1.1 joerg #include "clang/AST/Decl.h" 21 1.1 joerg #include "clang/AST/DeclBase.h" 22 1.1 joerg #include "clang/AST/DeclCXX.h" 23 1.1 joerg #include "clang/AST/DeclContextInternals.h" 24 1.1 joerg #include "clang/AST/DeclFriend.h" 25 1.1 joerg #include "clang/AST/DeclObjC.h" 26 1.1 joerg #include "clang/AST/DeclTemplate.h" 27 1.1 joerg #include "clang/AST/DeclarationName.h" 28 1.1 joerg #include "clang/AST/Expr.h" 29 1.1 joerg #include "clang/AST/ExprCXX.h" 30 1.1 joerg #include "clang/AST/LambdaCapture.h" 31 1.1 joerg #include "clang/AST/NestedNameSpecifier.h" 32 1.1.1.2 joerg #include "clang/AST/OpenMPClause.h" 33 1.1 joerg #include "clang/AST/RawCommentList.h" 34 1.1 joerg #include "clang/AST/TemplateName.h" 35 1.1 joerg #include "clang/AST/Type.h" 36 1.1 joerg #include "clang/AST/TypeLocVisitor.h" 37 1.1 joerg #include "clang/Basic/Diagnostic.h" 38 1.1 joerg #include "clang/Basic/DiagnosticOptions.h" 39 1.1 joerg #include "clang/Basic/FileManager.h" 40 1.1 joerg #include "clang/Basic/FileSystemOptions.h" 41 1.1 joerg #include "clang/Basic/IdentifierTable.h" 42 1.1 joerg #include "clang/Basic/LLVM.h" 43 1.1 joerg #include "clang/Basic/Lambda.h" 44 1.1 joerg #include "clang/Basic/LangOptions.h" 45 1.1 joerg #include "clang/Basic/Module.h" 46 1.1 joerg #include "clang/Basic/ObjCRuntime.h" 47 1.1 joerg #include "clang/Basic/OpenCLOptions.h" 48 1.1 joerg #include "clang/Basic/SourceLocation.h" 49 1.1 joerg #include "clang/Basic/SourceManager.h" 50 1.1 joerg #include "clang/Basic/SourceManagerInternals.h" 51 1.1 joerg #include "clang/Basic/Specifiers.h" 52 1.1 joerg #include "clang/Basic/TargetInfo.h" 53 1.1 joerg #include "clang/Basic/TargetOptions.h" 54 1.1 joerg #include "clang/Basic/Version.h" 55 1.1 joerg #include "clang/Lex/HeaderSearch.h" 56 1.1 joerg #include "clang/Lex/HeaderSearchOptions.h" 57 1.1 joerg #include "clang/Lex/MacroInfo.h" 58 1.1 joerg #include "clang/Lex/ModuleMap.h" 59 1.1 joerg #include "clang/Lex/PreprocessingRecord.h" 60 1.1 joerg #include "clang/Lex/Preprocessor.h" 61 1.1 joerg #include "clang/Lex/PreprocessorOptions.h" 62 1.1 joerg #include "clang/Lex/Token.h" 63 1.1 joerg #include "clang/Sema/IdentifierResolver.h" 64 1.1 joerg #include "clang/Sema/ObjCMethodList.h" 65 1.1 joerg #include "clang/Sema/Sema.h" 66 1.1 joerg #include "clang/Sema/Weak.h" 67 1.1.1.2 joerg #include "clang/Serialization/ASTBitCodes.h" 68 1.1 joerg #include "clang/Serialization/ASTReader.h" 69 1.1.1.2 joerg #include "clang/Serialization/ASTRecordWriter.h" 70 1.1 joerg #include "clang/Serialization/InMemoryModuleCache.h" 71 1.1.1.2 joerg #include "clang/Serialization/ModuleFile.h" 72 1.1 joerg #include "clang/Serialization/ModuleFileExtension.h" 73 1.1 joerg #include "clang/Serialization/SerializationDiagnostic.h" 74 1.1 joerg #include "llvm/ADT/APFloat.h" 75 1.1 joerg #include "llvm/ADT/APInt.h" 76 1.1 joerg #include "llvm/ADT/APSInt.h" 77 1.1 joerg #include "llvm/ADT/ArrayRef.h" 78 1.1 joerg #include "llvm/ADT/DenseMap.h" 79 1.1 joerg #include "llvm/ADT/Hashing.h" 80 1.1 joerg #include "llvm/ADT/Optional.h" 81 1.1 joerg #include "llvm/ADT/PointerIntPair.h" 82 1.1 joerg #include "llvm/ADT/STLExtras.h" 83 1.1 joerg #include "llvm/ADT/ScopeExit.h" 84 1.1.1.2 joerg #include "llvm/ADT/SmallPtrSet.h" 85 1.1 joerg #include "llvm/ADT/SmallString.h" 86 1.1 joerg #include "llvm/ADT/SmallVector.h" 87 1.1 joerg #include "llvm/ADT/StringMap.h" 88 1.1 joerg #include "llvm/ADT/StringRef.h" 89 1.1 joerg #include "llvm/Bitstream/BitCodes.h" 90 1.1 joerg #include "llvm/Bitstream/BitstreamWriter.h" 91 1.1 joerg #include "llvm/Support/Casting.h" 92 1.1 joerg #include "llvm/Support/Compression.h" 93 1.1 joerg #include "llvm/Support/DJB.h" 94 1.1 joerg #include "llvm/Support/Endian.h" 95 1.1 joerg #include "llvm/Support/EndianStream.h" 96 1.1 joerg #include "llvm/Support/Error.h" 97 1.1 joerg #include "llvm/Support/ErrorHandling.h" 98 1.1.1.2 joerg #include "llvm/Support/LEB128.h" 99 1.1 joerg #include "llvm/Support/MemoryBuffer.h" 100 1.1 joerg #include "llvm/Support/OnDiskHashTable.h" 101 1.1 joerg #include "llvm/Support/Path.h" 102 1.1 joerg #include "llvm/Support/SHA1.h" 103 1.1 joerg #include "llvm/Support/VersionTuple.h" 104 1.1 joerg #include "llvm/Support/raw_ostream.h" 105 1.1 joerg #include <algorithm> 106 1.1 joerg #include <cassert> 107 1.1 joerg #include <cstdint> 108 1.1 joerg #include <cstdlib> 109 1.1 joerg #include <cstring> 110 1.1 joerg #include <ctime> 111 1.1 joerg #include <deque> 112 1.1 joerg #include <limits> 113 1.1 joerg #include <memory> 114 1.1 joerg #include <queue> 115 1.1 joerg #include <tuple> 116 1.1 joerg #include <utility> 117 1.1 joerg #include <vector> 118 1.1 joerg 119 1.1 joerg using namespace clang; 120 1.1 joerg using namespace clang::serialization; 121 1.1 joerg 122 1.1 joerg template <typename T, typename Allocator> 123 1.1 joerg static StringRef bytes(const std::vector<T, Allocator> &v) { 124 1.1 joerg if (v.empty()) return StringRef(); 125 1.1 joerg return StringRef(reinterpret_cast<const char*>(&v[0]), 126 1.1 joerg sizeof(T) * v.size()); 127 1.1 joerg } 128 1.1 joerg 129 1.1 joerg template <typename T> 130 1.1 joerg static StringRef bytes(const SmallVectorImpl<T> &v) { 131 1.1 joerg return StringRef(reinterpret_cast<const char*>(v.data()), 132 1.1 joerg sizeof(T) * v.size()); 133 1.1 joerg } 134 1.1 joerg 135 1.1 joerg //===----------------------------------------------------------------------===// 136 1.1 joerg // Type serialization 137 1.1 joerg //===----------------------------------------------------------------------===// 138 1.1 joerg 139 1.1.1.2 joerg static TypeCode getTypeCodeForTypeClass(Type::TypeClass id) { 140 1.1.1.2 joerg switch (id) { 141 1.1.1.2 joerg #define TYPE_BIT_CODE(CLASS_ID, CODE_ID, CODE_VALUE) \ 142 1.1.1.2 joerg case Type::CLASS_ID: return TYPE_##CODE_ID; 143 1.1.1.2 joerg #include "clang/Serialization/TypeBitCodes.def" 144 1.1.1.2 joerg case Type::Builtin: 145 1.1.1.2 joerg llvm_unreachable("shouldn't be serializing a builtin type this way"); 146 1.1 joerg } 147 1.1.1.2 joerg llvm_unreachable("bad type kind"); 148 1.1 joerg } 149 1.1 joerg 150 1.1.1.2 joerg namespace { 151 1.1 joerg 152 1.1.1.2 joerg class ASTTypeWriter { 153 1.1.1.2 joerg ASTWriter &Writer; 154 1.1.1.2 joerg ASTWriter::RecordData Record; 155 1.1.1.2 joerg ASTRecordWriter BasicWriter; 156 1.1 joerg 157 1.1.1.2 joerg public: 158 1.1.1.2 joerg ASTTypeWriter(ASTWriter &Writer) 159 1.1.1.2 joerg : Writer(Writer), BasicWriter(Writer, Record) {} 160 1.1 joerg 161 1.1.1.2 joerg uint64_t write(QualType T) { 162 1.1.1.2 joerg if (T.hasLocalNonFastQualifiers()) { 163 1.1.1.2 joerg Qualifiers Qs = T.getLocalQualifiers(); 164 1.1.1.2 joerg BasicWriter.writeQualType(T.getLocalUnqualifiedType()); 165 1.1.1.2 joerg BasicWriter.writeQualifiers(Qs); 166 1.1.1.2 joerg return BasicWriter.Emit(TYPE_EXT_QUAL, Writer.getTypeExtQualAbbrev()); 167 1.1.1.2 joerg } 168 1.1.1.2 joerg 169 1.1.1.2 joerg const Type *typePtr = T.getTypePtr(); 170 1.1.1.2 joerg serialization::AbstractTypeWriter<ASTRecordWriter> atw(BasicWriter); 171 1.1.1.2 joerg atw.write(typePtr); 172 1.1.1.2 joerg return BasicWriter.Emit(getTypeCodeForTypeClass(typePtr->getTypeClass()), 173 1.1.1.2 joerg /*abbrev*/ 0); 174 1.1 joerg } 175 1.1.1.2 joerg }; 176 1.1 joerg 177 1.1 joerg class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { 178 1.1 joerg ASTRecordWriter &Record; 179 1.1 joerg 180 1.1 joerg public: 181 1.1 joerg TypeLocWriter(ASTRecordWriter &Record) : Record(Record) {} 182 1.1 joerg 183 1.1 joerg #define ABSTRACT_TYPELOC(CLASS, PARENT) 184 1.1 joerg #define TYPELOC(CLASS, PARENT) \ 185 1.1 joerg void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 186 1.1 joerg #include "clang/AST/TypeLocNodes.def" 187 1.1 joerg 188 1.1 joerg void VisitArrayTypeLoc(ArrayTypeLoc TyLoc); 189 1.1 joerg void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc); 190 1.1 joerg }; 191 1.1 joerg 192 1.1 joerg } // namespace 193 1.1 joerg 194 1.1 joerg void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 195 1.1 joerg // nothing to do 196 1.1 joerg } 197 1.1 joerg 198 1.1 joerg void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 199 1.1 joerg Record.AddSourceLocation(TL.getBuiltinLoc()); 200 1.1 joerg if (TL.needsExtraLocalData()) { 201 1.1 joerg Record.push_back(TL.getWrittenTypeSpec()); 202 1.1.1.2 joerg Record.push_back(static_cast<uint64_t>(TL.getWrittenSignSpec())); 203 1.1.1.2 joerg Record.push_back(static_cast<uint64_t>(TL.getWrittenWidthSpec())); 204 1.1 joerg Record.push_back(TL.hasModeAttr()); 205 1.1 joerg } 206 1.1 joerg } 207 1.1 joerg 208 1.1 joerg void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { 209 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 210 1.1 joerg } 211 1.1 joerg 212 1.1 joerg void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { 213 1.1 joerg Record.AddSourceLocation(TL.getStarLoc()); 214 1.1 joerg } 215 1.1 joerg 216 1.1 joerg void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) { 217 1.1 joerg // nothing to do 218 1.1 joerg } 219 1.1 joerg 220 1.1 joerg void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { 221 1.1 joerg // nothing to do 222 1.1 joerg } 223 1.1 joerg 224 1.1 joerg void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 225 1.1 joerg Record.AddSourceLocation(TL.getCaretLoc()); 226 1.1 joerg } 227 1.1 joerg 228 1.1 joerg void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 229 1.1 joerg Record.AddSourceLocation(TL.getAmpLoc()); 230 1.1 joerg } 231 1.1 joerg 232 1.1 joerg void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 233 1.1 joerg Record.AddSourceLocation(TL.getAmpAmpLoc()); 234 1.1 joerg } 235 1.1 joerg 236 1.1 joerg void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 237 1.1 joerg Record.AddSourceLocation(TL.getStarLoc()); 238 1.1 joerg Record.AddTypeSourceInfo(TL.getClassTInfo()); 239 1.1 joerg } 240 1.1 joerg 241 1.1 joerg void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { 242 1.1 joerg Record.AddSourceLocation(TL.getLBracketLoc()); 243 1.1 joerg Record.AddSourceLocation(TL.getRBracketLoc()); 244 1.1 joerg Record.push_back(TL.getSizeExpr() ? 1 : 0); 245 1.1 joerg if (TL.getSizeExpr()) 246 1.1 joerg Record.AddStmt(TL.getSizeExpr()); 247 1.1 joerg } 248 1.1 joerg 249 1.1 joerg void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { 250 1.1 joerg VisitArrayTypeLoc(TL); 251 1.1 joerg } 252 1.1 joerg 253 1.1 joerg void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { 254 1.1 joerg VisitArrayTypeLoc(TL); 255 1.1 joerg } 256 1.1 joerg 257 1.1 joerg void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { 258 1.1 joerg VisitArrayTypeLoc(TL); 259 1.1 joerg } 260 1.1 joerg 261 1.1 joerg void TypeLocWriter::VisitDependentSizedArrayTypeLoc( 262 1.1 joerg DependentSizedArrayTypeLoc TL) { 263 1.1 joerg VisitArrayTypeLoc(TL); 264 1.1 joerg } 265 1.1 joerg 266 1.1 joerg void TypeLocWriter::VisitDependentAddressSpaceTypeLoc( 267 1.1 joerg DependentAddressSpaceTypeLoc TL) { 268 1.1 joerg Record.AddSourceLocation(TL.getAttrNameLoc()); 269 1.1 joerg SourceRange range = TL.getAttrOperandParensRange(); 270 1.1 joerg Record.AddSourceLocation(range.getBegin()); 271 1.1 joerg Record.AddSourceLocation(range.getEnd()); 272 1.1 joerg Record.AddStmt(TL.getAttrExprOperand()); 273 1.1 joerg } 274 1.1 joerg 275 1.1 joerg void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( 276 1.1 joerg DependentSizedExtVectorTypeLoc TL) { 277 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 278 1.1 joerg } 279 1.1 joerg 280 1.1 joerg void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { 281 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 282 1.1 joerg } 283 1.1 joerg 284 1.1 joerg void TypeLocWriter::VisitDependentVectorTypeLoc( 285 1.1 joerg DependentVectorTypeLoc TL) { 286 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 287 1.1 joerg } 288 1.1 joerg 289 1.1 joerg void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { 290 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 291 1.1 joerg } 292 1.1 joerg 293 1.1.1.2 joerg void TypeLocWriter::VisitConstantMatrixTypeLoc(ConstantMatrixTypeLoc TL) { 294 1.1.1.2 joerg Record.AddSourceLocation(TL.getAttrNameLoc()); 295 1.1.1.2 joerg SourceRange range = TL.getAttrOperandParensRange(); 296 1.1.1.2 joerg Record.AddSourceLocation(range.getBegin()); 297 1.1.1.2 joerg Record.AddSourceLocation(range.getEnd()); 298 1.1.1.2 joerg Record.AddStmt(TL.getAttrRowOperand()); 299 1.1.1.2 joerg Record.AddStmt(TL.getAttrColumnOperand()); 300 1.1.1.2 joerg } 301 1.1.1.2 joerg 302 1.1.1.2 joerg void TypeLocWriter::VisitDependentSizedMatrixTypeLoc( 303 1.1.1.2 joerg DependentSizedMatrixTypeLoc TL) { 304 1.1.1.2 joerg Record.AddSourceLocation(TL.getAttrNameLoc()); 305 1.1.1.2 joerg SourceRange range = TL.getAttrOperandParensRange(); 306 1.1.1.2 joerg Record.AddSourceLocation(range.getBegin()); 307 1.1.1.2 joerg Record.AddSourceLocation(range.getEnd()); 308 1.1.1.2 joerg Record.AddStmt(TL.getAttrRowOperand()); 309 1.1.1.2 joerg Record.AddStmt(TL.getAttrColumnOperand()); 310 1.1.1.2 joerg } 311 1.1.1.2 joerg 312 1.1 joerg void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { 313 1.1 joerg Record.AddSourceLocation(TL.getLocalRangeBegin()); 314 1.1 joerg Record.AddSourceLocation(TL.getLParenLoc()); 315 1.1 joerg Record.AddSourceLocation(TL.getRParenLoc()); 316 1.1 joerg Record.AddSourceRange(TL.getExceptionSpecRange()); 317 1.1 joerg Record.AddSourceLocation(TL.getLocalRangeEnd()); 318 1.1 joerg for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) 319 1.1 joerg Record.AddDeclRef(TL.getParam(i)); 320 1.1 joerg } 321 1.1 joerg 322 1.1 joerg void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { 323 1.1 joerg VisitFunctionTypeLoc(TL); 324 1.1 joerg } 325 1.1 joerg 326 1.1 joerg void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { 327 1.1 joerg VisitFunctionTypeLoc(TL); 328 1.1 joerg } 329 1.1 joerg 330 1.1 joerg void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 331 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 332 1.1 joerg } 333 1.1 joerg 334 1.1 joerg void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 335 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 336 1.1 joerg } 337 1.1 joerg 338 1.1 joerg void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) { 339 1.1 joerg if (TL.getNumProtocols()) { 340 1.1 joerg Record.AddSourceLocation(TL.getProtocolLAngleLoc()); 341 1.1 joerg Record.AddSourceLocation(TL.getProtocolRAngleLoc()); 342 1.1 joerg } 343 1.1 joerg for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) 344 1.1 joerg Record.AddSourceLocation(TL.getProtocolLoc(i)); 345 1.1 joerg } 346 1.1 joerg 347 1.1 joerg void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 348 1.1 joerg Record.AddSourceLocation(TL.getTypeofLoc()); 349 1.1 joerg Record.AddSourceLocation(TL.getLParenLoc()); 350 1.1 joerg Record.AddSourceLocation(TL.getRParenLoc()); 351 1.1 joerg } 352 1.1 joerg 353 1.1 joerg void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 354 1.1 joerg Record.AddSourceLocation(TL.getTypeofLoc()); 355 1.1 joerg Record.AddSourceLocation(TL.getLParenLoc()); 356 1.1 joerg Record.AddSourceLocation(TL.getRParenLoc()); 357 1.1 joerg Record.AddTypeSourceInfo(TL.getUnderlyingTInfo()); 358 1.1 joerg } 359 1.1 joerg 360 1.1 joerg void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 361 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 362 1.1 joerg } 363 1.1 joerg 364 1.1 joerg void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { 365 1.1 joerg Record.AddSourceLocation(TL.getKWLoc()); 366 1.1 joerg Record.AddSourceLocation(TL.getLParenLoc()); 367 1.1 joerg Record.AddSourceLocation(TL.getRParenLoc()); 368 1.1 joerg Record.AddTypeSourceInfo(TL.getUnderlyingTInfo()); 369 1.1 joerg } 370 1.1 joerg 371 1.1 joerg void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { 372 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 373 1.1.1.2 joerg Record.push_back(TL.isConstrained()); 374 1.1.1.2 joerg if (TL.isConstrained()) { 375 1.1.1.2 joerg Record.AddNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()); 376 1.1.1.2 joerg Record.AddSourceLocation(TL.getTemplateKWLoc()); 377 1.1.1.2 joerg Record.AddSourceLocation(TL.getConceptNameLoc()); 378 1.1.1.2 joerg Record.AddDeclRef(TL.getFoundDecl()); 379 1.1.1.2 joerg Record.AddSourceLocation(TL.getLAngleLoc()); 380 1.1.1.2 joerg Record.AddSourceLocation(TL.getRAngleLoc()); 381 1.1.1.2 joerg for (unsigned I = 0; I < TL.getNumArgs(); ++I) 382 1.1.1.2 joerg Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(), 383 1.1.1.2 joerg TL.getArgLocInfo(I)); 384 1.1.1.2 joerg } 385 1.1 joerg } 386 1.1 joerg 387 1.1 joerg void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc( 388 1.1 joerg DeducedTemplateSpecializationTypeLoc TL) { 389 1.1 joerg Record.AddSourceLocation(TL.getTemplateNameLoc()); 390 1.1 joerg } 391 1.1 joerg 392 1.1 joerg void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { 393 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 394 1.1 joerg } 395 1.1 joerg 396 1.1 joerg void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { 397 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 398 1.1 joerg } 399 1.1 joerg 400 1.1 joerg void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) { 401 1.1 joerg Record.AddAttr(TL.getAttr()); 402 1.1 joerg } 403 1.1 joerg 404 1.1 joerg void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 405 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 406 1.1 joerg } 407 1.1 joerg 408 1.1 joerg void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( 409 1.1 joerg SubstTemplateTypeParmTypeLoc TL) { 410 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 411 1.1 joerg } 412 1.1 joerg 413 1.1 joerg void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc( 414 1.1 joerg SubstTemplateTypeParmPackTypeLoc TL) { 415 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 416 1.1 joerg } 417 1.1 joerg 418 1.1 joerg void TypeLocWriter::VisitTemplateSpecializationTypeLoc( 419 1.1 joerg TemplateSpecializationTypeLoc TL) { 420 1.1 joerg Record.AddSourceLocation(TL.getTemplateKeywordLoc()); 421 1.1 joerg Record.AddSourceLocation(TL.getTemplateNameLoc()); 422 1.1 joerg Record.AddSourceLocation(TL.getLAngleLoc()); 423 1.1 joerg Record.AddSourceLocation(TL.getRAngleLoc()); 424 1.1 joerg for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 425 1.1 joerg Record.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(), 426 1.1 joerg TL.getArgLoc(i).getLocInfo()); 427 1.1 joerg } 428 1.1 joerg 429 1.1 joerg void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) { 430 1.1 joerg Record.AddSourceLocation(TL.getLParenLoc()); 431 1.1 joerg Record.AddSourceLocation(TL.getRParenLoc()); 432 1.1 joerg } 433 1.1 joerg 434 1.1 joerg void TypeLocWriter::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { 435 1.1 joerg Record.AddSourceLocation(TL.getExpansionLoc()); 436 1.1 joerg } 437 1.1 joerg 438 1.1 joerg void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { 439 1.1 joerg Record.AddSourceLocation(TL.getElaboratedKeywordLoc()); 440 1.1 joerg Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc()); 441 1.1 joerg } 442 1.1 joerg 443 1.1 joerg void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 444 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 445 1.1 joerg } 446 1.1 joerg 447 1.1 joerg void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { 448 1.1 joerg Record.AddSourceLocation(TL.getElaboratedKeywordLoc()); 449 1.1 joerg Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc()); 450 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 451 1.1 joerg } 452 1.1 joerg 453 1.1 joerg void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( 454 1.1 joerg DependentTemplateSpecializationTypeLoc TL) { 455 1.1 joerg Record.AddSourceLocation(TL.getElaboratedKeywordLoc()); 456 1.1 joerg Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc()); 457 1.1 joerg Record.AddSourceLocation(TL.getTemplateKeywordLoc()); 458 1.1 joerg Record.AddSourceLocation(TL.getTemplateNameLoc()); 459 1.1 joerg Record.AddSourceLocation(TL.getLAngleLoc()); 460 1.1 joerg Record.AddSourceLocation(TL.getRAngleLoc()); 461 1.1 joerg for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) 462 1.1 joerg Record.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(), 463 1.1 joerg TL.getArgLoc(I).getLocInfo()); 464 1.1 joerg } 465 1.1 joerg 466 1.1 joerg void TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { 467 1.1 joerg Record.AddSourceLocation(TL.getEllipsisLoc()); 468 1.1 joerg } 469 1.1 joerg 470 1.1 joerg void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 471 1.1 joerg Record.AddSourceLocation(TL.getNameLoc()); 472 1.1 joerg } 473 1.1 joerg 474 1.1 joerg void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 475 1.1 joerg Record.push_back(TL.hasBaseTypeAsWritten()); 476 1.1 joerg Record.AddSourceLocation(TL.getTypeArgsLAngleLoc()); 477 1.1 joerg Record.AddSourceLocation(TL.getTypeArgsRAngleLoc()); 478 1.1 joerg for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i) 479 1.1 joerg Record.AddTypeSourceInfo(TL.getTypeArgTInfo(i)); 480 1.1 joerg Record.AddSourceLocation(TL.getProtocolLAngleLoc()); 481 1.1 joerg Record.AddSourceLocation(TL.getProtocolRAngleLoc()); 482 1.1 joerg for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) 483 1.1 joerg Record.AddSourceLocation(TL.getProtocolLoc(i)); 484 1.1 joerg } 485 1.1 joerg 486 1.1 joerg void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 487 1.1 joerg Record.AddSourceLocation(TL.getStarLoc()); 488 1.1 joerg } 489 1.1 joerg 490 1.1 joerg void TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) { 491 1.1 joerg Record.AddSourceLocation(TL.getKWLoc()); 492 1.1 joerg Record.AddSourceLocation(TL.getLParenLoc()); 493 1.1 joerg Record.AddSourceLocation(TL.getRParenLoc()); 494 1.1 joerg } 495 1.1 joerg 496 1.1 joerg void TypeLocWriter::VisitPipeTypeLoc(PipeTypeLoc TL) { 497 1.1 joerg Record.AddSourceLocation(TL.getKWLoc()); 498 1.1 joerg } 499 1.1 joerg 500 1.1.1.2 joerg void TypeLocWriter::VisitExtIntTypeLoc(clang::ExtIntTypeLoc TL) { 501 1.1.1.2 joerg Record.AddSourceLocation(TL.getNameLoc()); 502 1.1.1.2 joerg } 503 1.1.1.2 joerg void TypeLocWriter::VisitDependentExtIntTypeLoc( 504 1.1.1.2 joerg clang::DependentExtIntTypeLoc TL) { 505 1.1.1.2 joerg Record.AddSourceLocation(TL.getNameLoc()); 506 1.1.1.2 joerg } 507 1.1.1.2 joerg 508 1.1 joerg void ASTWriter::WriteTypeAbbrevs() { 509 1.1 joerg using namespace llvm; 510 1.1 joerg 511 1.1 joerg std::shared_ptr<BitCodeAbbrev> Abv; 512 1.1 joerg 513 1.1 joerg // Abbreviation for TYPE_EXT_QUAL 514 1.1 joerg Abv = std::make_shared<BitCodeAbbrev>(); 515 1.1 joerg Abv->Add(BitCodeAbbrevOp(serialization::TYPE_EXT_QUAL)); 516 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type 517 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3)); // Quals 518 1.1 joerg TypeExtQualAbbrev = Stream.EmitAbbrev(std::move(Abv)); 519 1.1 joerg 520 1.1 joerg // Abbreviation for TYPE_FUNCTION_PROTO 521 1.1 joerg Abv = std::make_shared<BitCodeAbbrev>(); 522 1.1 joerg Abv->Add(BitCodeAbbrevOp(serialization::TYPE_FUNCTION_PROTO)); 523 1.1 joerg // FunctionType 524 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ReturnType 525 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // NoReturn 526 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // HasRegParm 527 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // RegParm 528 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC 529 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult 530 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // NoCallerSavedRegs 531 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // NoCfCheck 532 1.1.1.2 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CmseNSCall 533 1.1 joerg // FunctionProtoType 534 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic 535 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn 536 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // TypeQuals 537 1.1 joerg Abv->Add(BitCodeAbbrevOp(0)); // RefQualifier 538 1.1 joerg Abv->Add(BitCodeAbbrevOp(EST_None)); // ExceptionSpec 539 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumParams 540 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 541 1.1 joerg Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Params 542 1.1 joerg TypeFunctionProtoAbbrev = Stream.EmitAbbrev(std::move(Abv)); 543 1.1 joerg } 544 1.1 joerg 545 1.1 joerg //===----------------------------------------------------------------------===// 546 1.1 joerg // ASTWriter Implementation 547 1.1 joerg //===----------------------------------------------------------------------===// 548 1.1 joerg 549 1.1 joerg static void EmitBlockID(unsigned ID, const char *Name, 550 1.1 joerg llvm::BitstreamWriter &Stream, 551 1.1 joerg ASTWriter::RecordDataImpl &Record) { 552 1.1 joerg Record.clear(); 553 1.1 joerg Record.push_back(ID); 554 1.1 joerg Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); 555 1.1 joerg 556 1.1 joerg // Emit the block name if present. 557 1.1 joerg if (!Name || Name[0] == 0) 558 1.1 joerg return; 559 1.1 joerg Record.clear(); 560 1.1 joerg while (*Name) 561 1.1 joerg Record.push_back(*Name++); 562 1.1 joerg Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record); 563 1.1 joerg } 564 1.1 joerg 565 1.1 joerg static void EmitRecordID(unsigned ID, const char *Name, 566 1.1 joerg llvm::BitstreamWriter &Stream, 567 1.1 joerg ASTWriter::RecordDataImpl &Record) { 568 1.1 joerg Record.clear(); 569 1.1 joerg Record.push_back(ID); 570 1.1 joerg while (*Name) 571 1.1 joerg Record.push_back(*Name++); 572 1.1 joerg Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record); 573 1.1 joerg } 574 1.1 joerg 575 1.1 joerg static void AddStmtsExprs(llvm::BitstreamWriter &Stream, 576 1.1 joerg ASTWriter::RecordDataImpl &Record) { 577 1.1 joerg #define RECORD(X) EmitRecordID(X, #X, Stream, Record) 578 1.1 joerg RECORD(STMT_STOP); 579 1.1 joerg RECORD(STMT_NULL_PTR); 580 1.1 joerg RECORD(STMT_REF_PTR); 581 1.1 joerg RECORD(STMT_NULL); 582 1.1 joerg RECORD(STMT_COMPOUND); 583 1.1 joerg RECORD(STMT_CASE); 584 1.1 joerg RECORD(STMT_DEFAULT); 585 1.1 joerg RECORD(STMT_LABEL); 586 1.1 joerg RECORD(STMT_ATTRIBUTED); 587 1.1 joerg RECORD(STMT_IF); 588 1.1 joerg RECORD(STMT_SWITCH); 589 1.1 joerg RECORD(STMT_WHILE); 590 1.1 joerg RECORD(STMT_DO); 591 1.1 joerg RECORD(STMT_FOR); 592 1.1 joerg RECORD(STMT_GOTO); 593 1.1 joerg RECORD(STMT_INDIRECT_GOTO); 594 1.1 joerg RECORD(STMT_CONTINUE); 595 1.1 joerg RECORD(STMT_BREAK); 596 1.1 joerg RECORD(STMT_RETURN); 597 1.1 joerg RECORD(STMT_DECL); 598 1.1 joerg RECORD(STMT_GCCASM); 599 1.1 joerg RECORD(STMT_MSASM); 600 1.1 joerg RECORD(EXPR_PREDEFINED); 601 1.1 joerg RECORD(EXPR_DECL_REF); 602 1.1 joerg RECORD(EXPR_INTEGER_LITERAL); 603 1.1.1.2 joerg RECORD(EXPR_FIXEDPOINT_LITERAL); 604 1.1 joerg RECORD(EXPR_FLOATING_LITERAL); 605 1.1 joerg RECORD(EXPR_IMAGINARY_LITERAL); 606 1.1 joerg RECORD(EXPR_STRING_LITERAL); 607 1.1 joerg RECORD(EXPR_CHARACTER_LITERAL); 608 1.1 joerg RECORD(EXPR_PAREN); 609 1.1 joerg RECORD(EXPR_PAREN_LIST); 610 1.1 joerg RECORD(EXPR_UNARY_OPERATOR); 611 1.1 joerg RECORD(EXPR_SIZEOF_ALIGN_OF); 612 1.1 joerg RECORD(EXPR_ARRAY_SUBSCRIPT); 613 1.1 joerg RECORD(EXPR_CALL); 614 1.1 joerg RECORD(EXPR_MEMBER); 615 1.1 joerg RECORD(EXPR_BINARY_OPERATOR); 616 1.1 joerg RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR); 617 1.1 joerg RECORD(EXPR_CONDITIONAL_OPERATOR); 618 1.1 joerg RECORD(EXPR_IMPLICIT_CAST); 619 1.1 joerg RECORD(EXPR_CSTYLE_CAST); 620 1.1 joerg RECORD(EXPR_COMPOUND_LITERAL); 621 1.1 joerg RECORD(EXPR_EXT_VECTOR_ELEMENT); 622 1.1 joerg RECORD(EXPR_INIT_LIST); 623 1.1 joerg RECORD(EXPR_DESIGNATED_INIT); 624 1.1 joerg RECORD(EXPR_DESIGNATED_INIT_UPDATE); 625 1.1 joerg RECORD(EXPR_IMPLICIT_VALUE_INIT); 626 1.1 joerg RECORD(EXPR_NO_INIT); 627 1.1 joerg RECORD(EXPR_VA_ARG); 628 1.1 joerg RECORD(EXPR_ADDR_LABEL); 629 1.1 joerg RECORD(EXPR_STMT); 630 1.1 joerg RECORD(EXPR_CHOOSE); 631 1.1 joerg RECORD(EXPR_GNU_NULL); 632 1.1 joerg RECORD(EXPR_SHUFFLE_VECTOR); 633 1.1 joerg RECORD(EXPR_BLOCK); 634 1.1 joerg RECORD(EXPR_GENERIC_SELECTION); 635 1.1 joerg RECORD(EXPR_OBJC_STRING_LITERAL); 636 1.1 joerg RECORD(EXPR_OBJC_BOXED_EXPRESSION); 637 1.1 joerg RECORD(EXPR_OBJC_ARRAY_LITERAL); 638 1.1 joerg RECORD(EXPR_OBJC_DICTIONARY_LITERAL); 639 1.1 joerg RECORD(EXPR_OBJC_ENCODE); 640 1.1 joerg RECORD(EXPR_OBJC_SELECTOR_EXPR); 641 1.1 joerg RECORD(EXPR_OBJC_PROTOCOL_EXPR); 642 1.1 joerg RECORD(EXPR_OBJC_IVAR_REF_EXPR); 643 1.1 joerg RECORD(EXPR_OBJC_PROPERTY_REF_EXPR); 644 1.1 joerg RECORD(EXPR_OBJC_KVC_REF_EXPR); 645 1.1 joerg RECORD(EXPR_OBJC_MESSAGE_EXPR); 646 1.1 joerg RECORD(STMT_OBJC_FOR_COLLECTION); 647 1.1 joerg RECORD(STMT_OBJC_CATCH); 648 1.1 joerg RECORD(STMT_OBJC_FINALLY); 649 1.1 joerg RECORD(STMT_OBJC_AT_TRY); 650 1.1 joerg RECORD(STMT_OBJC_AT_SYNCHRONIZED); 651 1.1 joerg RECORD(STMT_OBJC_AT_THROW); 652 1.1 joerg RECORD(EXPR_OBJC_BOOL_LITERAL); 653 1.1 joerg RECORD(STMT_CXX_CATCH); 654 1.1 joerg RECORD(STMT_CXX_TRY); 655 1.1 joerg RECORD(STMT_CXX_FOR_RANGE); 656 1.1 joerg RECORD(EXPR_CXX_OPERATOR_CALL); 657 1.1 joerg RECORD(EXPR_CXX_MEMBER_CALL); 658 1.1 joerg RECORD(EXPR_CXX_REWRITTEN_BINARY_OPERATOR); 659 1.1 joerg RECORD(EXPR_CXX_CONSTRUCT); 660 1.1 joerg RECORD(EXPR_CXX_TEMPORARY_OBJECT); 661 1.1 joerg RECORD(EXPR_CXX_STATIC_CAST); 662 1.1 joerg RECORD(EXPR_CXX_DYNAMIC_CAST); 663 1.1 joerg RECORD(EXPR_CXX_REINTERPRET_CAST); 664 1.1 joerg RECORD(EXPR_CXX_CONST_CAST); 665 1.1.1.2 joerg RECORD(EXPR_CXX_ADDRSPACE_CAST); 666 1.1 joerg RECORD(EXPR_CXX_FUNCTIONAL_CAST); 667 1.1 joerg RECORD(EXPR_USER_DEFINED_LITERAL); 668 1.1 joerg RECORD(EXPR_CXX_STD_INITIALIZER_LIST); 669 1.1 joerg RECORD(EXPR_CXX_BOOL_LITERAL); 670 1.1 joerg RECORD(EXPR_CXX_NULL_PTR_LITERAL); 671 1.1 joerg RECORD(EXPR_CXX_TYPEID_EXPR); 672 1.1 joerg RECORD(EXPR_CXX_TYPEID_TYPE); 673 1.1 joerg RECORD(EXPR_CXX_THIS); 674 1.1 joerg RECORD(EXPR_CXX_THROW); 675 1.1 joerg RECORD(EXPR_CXX_DEFAULT_ARG); 676 1.1 joerg RECORD(EXPR_CXX_DEFAULT_INIT); 677 1.1 joerg RECORD(EXPR_CXX_BIND_TEMPORARY); 678 1.1 joerg RECORD(EXPR_CXX_SCALAR_VALUE_INIT); 679 1.1 joerg RECORD(EXPR_CXX_NEW); 680 1.1 joerg RECORD(EXPR_CXX_DELETE); 681 1.1 joerg RECORD(EXPR_CXX_PSEUDO_DESTRUCTOR); 682 1.1 joerg RECORD(EXPR_EXPR_WITH_CLEANUPS); 683 1.1 joerg RECORD(EXPR_CXX_DEPENDENT_SCOPE_MEMBER); 684 1.1 joerg RECORD(EXPR_CXX_DEPENDENT_SCOPE_DECL_REF); 685 1.1 joerg RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT); 686 1.1 joerg RECORD(EXPR_CXX_UNRESOLVED_MEMBER); 687 1.1 joerg RECORD(EXPR_CXX_UNRESOLVED_LOOKUP); 688 1.1 joerg RECORD(EXPR_CXX_EXPRESSION_TRAIT); 689 1.1 joerg RECORD(EXPR_CXX_NOEXCEPT); 690 1.1 joerg RECORD(EXPR_OPAQUE_VALUE); 691 1.1 joerg RECORD(EXPR_BINARY_CONDITIONAL_OPERATOR); 692 1.1 joerg RECORD(EXPR_TYPE_TRAIT); 693 1.1 joerg RECORD(EXPR_ARRAY_TYPE_TRAIT); 694 1.1 joerg RECORD(EXPR_PACK_EXPANSION); 695 1.1 joerg RECORD(EXPR_SIZEOF_PACK); 696 1.1 joerg RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM); 697 1.1 joerg RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK); 698 1.1 joerg RECORD(EXPR_FUNCTION_PARM_PACK); 699 1.1 joerg RECORD(EXPR_MATERIALIZE_TEMPORARY); 700 1.1 joerg RECORD(EXPR_CUDA_KERNEL_CALL); 701 1.1 joerg RECORD(EXPR_CXX_UUIDOF_EXPR); 702 1.1 joerg RECORD(EXPR_CXX_UUIDOF_TYPE); 703 1.1 joerg RECORD(EXPR_LAMBDA); 704 1.1 joerg #undef RECORD 705 1.1 joerg } 706 1.1 joerg 707 1.1 joerg void ASTWriter::WriteBlockInfoBlock() { 708 1.1 joerg RecordData Record; 709 1.1 joerg Stream.EnterBlockInfoBlock(); 710 1.1 joerg 711 1.1 joerg #define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record) 712 1.1 joerg #define RECORD(X) EmitRecordID(X, #X, Stream, Record) 713 1.1 joerg 714 1.1 joerg // Control Block. 715 1.1 joerg BLOCK(CONTROL_BLOCK); 716 1.1 joerg RECORD(METADATA); 717 1.1 joerg RECORD(MODULE_NAME); 718 1.1 joerg RECORD(MODULE_DIRECTORY); 719 1.1 joerg RECORD(MODULE_MAP_FILE); 720 1.1 joerg RECORD(IMPORTS); 721 1.1 joerg RECORD(ORIGINAL_FILE); 722 1.1 joerg RECORD(ORIGINAL_PCH_DIR); 723 1.1 joerg RECORD(ORIGINAL_FILE_ID); 724 1.1 joerg RECORD(INPUT_FILE_OFFSETS); 725 1.1 joerg 726 1.1 joerg BLOCK(OPTIONS_BLOCK); 727 1.1 joerg RECORD(LANGUAGE_OPTIONS); 728 1.1 joerg RECORD(TARGET_OPTIONS); 729 1.1 joerg RECORD(FILE_SYSTEM_OPTIONS); 730 1.1 joerg RECORD(HEADER_SEARCH_OPTIONS); 731 1.1 joerg RECORD(PREPROCESSOR_OPTIONS); 732 1.1 joerg 733 1.1 joerg BLOCK(INPUT_FILES_BLOCK); 734 1.1 joerg RECORD(INPUT_FILE); 735 1.1 joerg RECORD(INPUT_FILE_HASH); 736 1.1 joerg 737 1.1 joerg // AST Top-Level Block. 738 1.1 joerg BLOCK(AST_BLOCK); 739 1.1 joerg RECORD(TYPE_OFFSET); 740 1.1 joerg RECORD(DECL_OFFSET); 741 1.1 joerg RECORD(IDENTIFIER_OFFSET); 742 1.1 joerg RECORD(IDENTIFIER_TABLE); 743 1.1 joerg RECORD(EAGERLY_DESERIALIZED_DECLS); 744 1.1 joerg RECORD(MODULAR_CODEGEN_DECLS); 745 1.1 joerg RECORD(SPECIAL_TYPES); 746 1.1 joerg RECORD(STATISTICS); 747 1.1 joerg RECORD(TENTATIVE_DEFINITIONS); 748 1.1 joerg RECORD(SELECTOR_OFFSETS); 749 1.1 joerg RECORD(METHOD_POOL); 750 1.1 joerg RECORD(PP_COUNTER_VALUE); 751 1.1 joerg RECORD(SOURCE_LOCATION_OFFSETS); 752 1.1 joerg RECORD(SOURCE_LOCATION_PRELOADS); 753 1.1 joerg RECORD(EXT_VECTOR_DECLS); 754 1.1 joerg RECORD(UNUSED_FILESCOPED_DECLS); 755 1.1 joerg RECORD(PPD_ENTITIES_OFFSETS); 756 1.1 joerg RECORD(VTABLE_USES); 757 1.1 joerg RECORD(PPD_SKIPPED_RANGES); 758 1.1 joerg RECORD(REFERENCED_SELECTOR_POOL); 759 1.1 joerg RECORD(TU_UPDATE_LEXICAL); 760 1.1 joerg RECORD(SEMA_DECL_REFS); 761 1.1 joerg RECORD(WEAK_UNDECLARED_IDENTIFIERS); 762 1.1 joerg RECORD(PENDING_IMPLICIT_INSTANTIATIONS); 763 1.1 joerg RECORD(UPDATE_VISIBLE); 764 1.1 joerg RECORD(DECL_UPDATE_OFFSETS); 765 1.1 joerg RECORD(DECL_UPDATES); 766 1.1 joerg RECORD(CUDA_SPECIAL_DECL_REFS); 767 1.1 joerg RECORD(HEADER_SEARCH_TABLE); 768 1.1 joerg RECORD(FP_PRAGMA_OPTIONS); 769 1.1 joerg RECORD(OPENCL_EXTENSIONS); 770 1.1 joerg RECORD(OPENCL_EXTENSION_TYPES); 771 1.1 joerg RECORD(OPENCL_EXTENSION_DECLS); 772 1.1 joerg RECORD(DELEGATING_CTORS); 773 1.1 joerg RECORD(KNOWN_NAMESPACES); 774 1.1 joerg RECORD(MODULE_OFFSET_MAP); 775 1.1 joerg RECORD(SOURCE_MANAGER_LINE_TABLE); 776 1.1 joerg RECORD(OBJC_CATEGORIES_MAP); 777 1.1 joerg RECORD(FILE_SORTED_DECLS); 778 1.1 joerg RECORD(IMPORTED_MODULES); 779 1.1 joerg RECORD(OBJC_CATEGORIES); 780 1.1 joerg RECORD(MACRO_OFFSET); 781 1.1 joerg RECORD(INTERESTING_IDENTIFIERS); 782 1.1 joerg RECORD(UNDEFINED_BUT_USED); 783 1.1 joerg RECORD(LATE_PARSED_TEMPLATE); 784 1.1 joerg RECORD(OPTIMIZE_PRAGMA_OPTIONS); 785 1.1 joerg RECORD(MSSTRUCT_PRAGMA_OPTIONS); 786 1.1 joerg RECORD(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS); 787 1.1 joerg RECORD(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES); 788 1.1 joerg RECORD(DELETE_EXPRS_TO_ANALYZE); 789 1.1 joerg RECORD(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH); 790 1.1 joerg RECORD(PP_CONDITIONAL_STACK); 791 1.1.1.2 joerg RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS); 792 1.1 joerg 793 1.1 joerg // SourceManager Block. 794 1.1 joerg BLOCK(SOURCE_MANAGER_BLOCK); 795 1.1 joerg RECORD(SM_SLOC_FILE_ENTRY); 796 1.1 joerg RECORD(SM_SLOC_BUFFER_ENTRY); 797 1.1 joerg RECORD(SM_SLOC_BUFFER_BLOB); 798 1.1 joerg RECORD(SM_SLOC_BUFFER_BLOB_COMPRESSED); 799 1.1 joerg RECORD(SM_SLOC_EXPANSION_ENTRY); 800 1.1 joerg 801 1.1 joerg // Preprocessor Block. 802 1.1 joerg BLOCK(PREPROCESSOR_BLOCK); 803 1.1 joerg RECORD(PP_MACRO_DIRECTIVE_HISTORY); 804 1.1 joerg RECORD(PP_MACRO_FUNCTION_LIKE); 805 1.1 joerg RECORD(PP_MACRO_OBJECT_LIKE); 806 1.1 joerg RECORD(PP_MODULE_MACRO); 807 1.1 joerg RECORD(PP_TOKEN); 808 1.1 joerg 809 1.1 joerg // Submodule Block. 810 1.1 joerg BLOCK(SUBMODULE_BLOCK); 811 1.1 joerg RECORD(SUBMODULE_METADATA); 812 1.1 joerg RECORD(SUBMODULE_DEFINITION); 813 1.1 joerg RECORD(SUBMODULE_UMBRELLA_HEADER); 814 1.1 joerg RECORD(SUBMODULE_HEADER); 815 1.1 joerg RECORD(SUBMODULE_TOPHEADER); 816 1.1 joerg RECORD(SUBMODULE_UMBRELLA_DIR); 817 1.1 joerg RECORD(SUBMODULE_IMPORTS); 818 1.1 joerg RECORD(SUBMODULE_EXPORTS); 819 1.1 joerg RECORD(SUBMODULE_REQUIRES); 820 1.1 joerg RECORD(SUBMODULE_EXCLUDED_HEADER); 821 1.1 joerg RECORD(SUBMODULE_LINK_LIBRARY); 822 1.1 joerg RECORD(SUBMODULE_CONFIG_MACRO); 823 1.1 joerg RECORD(SUBMODULE_CONFLICT); 824 1.1 joerg RECORD(SUBMODULE_PRIVATE_HEADER); 825 1.1 joerg RECORD(SUBMODULE_TEXTUAL_HEADER); 826 1.1 joerg RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER); 827 1.1 joerg RECORD(SUBMODULE_INITIALIZERS); 828 1.1 joerg RECORD(SUBMODULE_EXPORT_AS); 829 1.1 joerg 830 1.1 joerg // Comments Block. 831 1.1 joerg BLOCK(COMMENTS_BLOCK); 832 1.1 joerg RECORD(COMMENTS_RAW_COMMENT); 833 1.1 joerg 834 1.1 joerg // Decls and Types block. 835 1.1 joerg BLOCK(DECLTYPES_BLOCK); 836 1.1 joerg RECORD(TYPE_EXT_QUAL); 837 1.1 joerg RECORD(TYPE_COMPLEX); 838 1.1 joerg RECORD(TYPE_POINTER); 839 1.1 joerg RECORD(TYPE_BLOCK_POINTER); 840 1.1 joerg RECORD(TYPE_LVALUE_REFERENCE); 841 1.1 joerg RECORD(TYPE_RVALUE_REFERENCE); 842 1.1 joerg RECORD(TYPE_MEMBER_POINTER); 843 1.1 joerg RECORD(TYPE_CONSTANT_ARRAY); 844 1.1 joerg RECORD(TYPE_INCOMPLETE_ARRAY); 845 1.1 joerg RECORD(TYPE_VARIABLE_ARRAY); 846 1.1 joerg RECORD(TYPE_VECTOR); 847 1.1 joerg RECORD(TYPE_EXT_VECTOR); 848 1.1 joerg RECORD(TYPE_FUNCTION_NO_PROTO); 849 1.1 joerg RECORD(TYPE_FUNCTION_PROTO); 850 1.1 joerg RECORD(TYPE_TYPEDEF); 851 1.1 joerg RECORD(TYPE_TYPEOF_EXPR); 852 1.1 joerg RECORD(TYPE_TYPEOF); 853 1.1 joerg RECORD(TYPE_RECORD); 854 1.1 joerg RECORD(TYPE_ENUM); 855 1.1 joerg RECORD(TYPE_OBJC_INTERFACE); 856 1.1 joerg RECORD(TYPE_OBJC_OBJECT_POINTER); 857 1.1 joerg RECORD(TYPE_DECLTYPE); 858 1.1 joerg RECORD(TYPE_ELABORATED); 859 1.1 joerg RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM); 860 1.1 joerg RECORD(TYPE_UNRESOLVED_USING); 861 1.1 joerg RECORD(TYPE_INJECTED_CLASS_NAME); 862 1.1 joerg RECORD(TYPE_OBJC_OBJECT); 863 1.1 joerg RECORD(TYPE_TEMPLATE_TYPE_PARM); 864 1.1 joerg RECORD(TYPE_TEMPLATE_SPECIALIZATION); 865 1.1 joerg RECORD(TYPE_DEPENDENT_NAME); 866 1.1 joerg RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION); 867 1.1 joerg RECORD(TYPE_DEPENDENT_SIZED_ARRAY); 868 1.1 joerg RECORD(TYPE_PAREN); 869 1.1 joerg RECORD(TYPE_MACRO_QUALIFIED); 870 1.1 joerg RECORD(TYPE_PACK_EXPANSION); 871 1.1 joerg RECORD(TYPE_ATTRIBUTED); 872 1.1 joerg RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK); 873 1.1 joerg RECORD(TYPE_AUTO); 874 1.1 joerg RECORD(TYPE_UNARY_TRANSFORM); 875 1.1 joerg RECORD(TYPE_ATOMIC); 876 1.1 joerg RECORD(TYPE_DECAYED); 877 1.1 joerg RECORD(TYPE_ADJUSTED); 878 1.1 joerg RECORD(TYPE_OBJC_TYPE_PARAM); 879 1.1 joerg RECORD(LOCAL_REDECLARATIONS); 880 1.1 joerg RECORD(DECL_TYPEDEF); 881 1.1 joerg RECORD(DECL_TYPEALIAS); 882 1.1 joerg RECORD(DECL_ENUM); 883 1.1 joerg RECORD(DECL_RECORD); 884 1.1 joerg RECORD(DECL_ENUM_CONSTANT); 885 1.1 joerg RECORD(DECL_FUNCTION); 886 1.1 joerg RECORD(DECL_OBJC_METHOD); 887 1.1 joerg RECORD(DECL_OBJC_INTERFACE); 888 1.1 joerg RECORD(DECL_OBJC_PROTOCOL); 889 1.1 joerg RECORD(DECL_OBJC_IVAR); 890 1.1 joerg RECORD(DECL_OBJC_AT_DEFS_FIELD); 891 1.1 joerg RECORD(DECL_OBJC_CATEGORY); 892 1.1 joerg RECORD(DECL_OBJC_CATEGORY_IMPL); 893 1.1 joerg RECORD(DECL_OBJC_IMPLEMENTATION); 894 1.1 joerg RECORD(DECL_OBJC_COMPATIBLE_ALIAS); 895 1.1 joerg RECORD(DECL_OBJC_PROPERTY); 896 1.1 joerg RECORD(DECL_OBJC_PROPERTY_IMPL); 897 1.1 joerg RECORD(DECL_FIELD); 898 1.1 joerg RECORD(DECL_MS_PROPERTY); 899 1.1 joerg RECORD(DECL_VAR); 900 1.1 joerg RECORD(DECL_IMPLICIT_PARAM); 901 1.1 joerg RECORD(DECL_PARM_VAR); 902 1.1 joerg RECORD(DECL_FILE_SCOPE_ASM); 903 1.1 joerg RECORD(DECL_BLOCK); 904 1.1 joerg RECORD(DECL_CONTEXT_LEXICAL); 905 1.1 joerg RECORD(DECL_CONTEXT_VISIBLE); 906 1.1 joerg RECORD(DECL_NAMESPACE); 907 1.1 joerg RECORD(DECL_NAMESPACE_ALIAS); 908 1.1 joerg RECORD(DECL_USING); 909 1.1 joerg RECORD(DECL_USING_SHADOW); 910 1.1 joerg RECORD(DECL_USING_DIRECTIVE); 911 1.1 joerg RECORD(DECL_UNRESOLVED_USING_VALUE); 912 1.1 joerg RECORD(DECL_UNRESOLVED_USING_TYPENAME); 913 1.1 joerg RECORD(DECL_LINKAGE_SPEC); 914 1.1 joerg RECORD(DECL_CXX_RECORD); 915 1.1 joerg RECORD(DECL_CXX_METHOD); 916 1.1 joerg RECORD(DECL_CXX_CONSTRUCTOR); 917 1.1 joerg RECORD(DECL_CXX_DESTRUCTOR); 918 1.1 joerg RECORD(DECL_CXX_CONVERSION); 919 1.1 joerg RECORD(DECL_ACCESS_SPEC); 920 1.1 joerg RECORD(DECL_FRIEND); 921 1.1 joerg RECORD(DECL_FRIEND_TEMPLATE); 922 1.1 joerg RECORD(DECL_CLASS_TEMPLATE); 923 1.1 joerg RECORD(DECL_CLASS_TEMPLATE_SPECIALIZATION); 924 1.1 joerg RECORD(DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION); 925 1.1 joerg RECORD(DECL_VAR_TEMPLATE); 926 1.1 joerg RECORD(DECL_VAR_TEMPLATE_SPECIALIZATION); 927 1.1 joerg RECORD(DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION); 928 1.1 joerg RECORD(DECL_FUNCTION_TEMPLATE); 929 1.1 joerg RECORD(DECL_TEMPLATE_TYPE_PARM); 930 1.1 joerg RECORD(DECL_NON_TYPE_TEMPLATE_PARM); 931 1.1 joerg RECORD(DECL_TEMPLATE_TEMPLATE_PARM); 932 1.1 joerg RECORD(DECL_CONCEPT); 933 1.1.1.2 joerg RECORD(DECL_REQUIRES_EXPR_BODY); 934 1.1 joerg RECORD(DECL_TYPE_ALIAS_TEMPLATE); 935 1.1 joerg RECORD(DECL_STATIC_ASSERT); 936 1.1 joerg RECORD(DECL_CXX_BASE_SPECIFIERS); 937 1.1 joerg RECORD(DECL_CXX_CTOR_INITIALIZERS); 938 1.1 joerg RECORD(DECL_INDIRECTFIELD); 939 1.1 joerg RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK); 940 1.1 joerg RECORD(DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK); 941 1.1 joerg RECORD(DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION); 942 1.1 joerg RECORD(DECL_IMPORT); 943 1.1 joerg RECORD(DECL_OMP_THREADPRIVATE); 944 1.1 joerg RECORD(DECL_EMPTY); 945 1.1 joerg RECORD(DECL_OBJC_TYPE_PARAM); 946 1.1 joerg RECORD(DECL_OMP_CAPTUREDEXPR); 947 1.1 joerg RECORD(DECL_PRAGMA_COMMENT); 948 1.1 joerg RECORD(DECL_PRAGMA_DETECT_MISMATCH); 949 1.1 joerg RECORD(DECL_OMP_DECLARE_REDUCTION); 950 1.1 joerg RECORD(DECL_OMP_ALLOCATE); 951 1.1 joerg 952 1.1 joerg // Statements and Exprs can occur in the Decls and Types block. 953 1.1 joerg AddStmtsExprs(Stream, Record); 954 1.1 joerg 955 1.1 joerg BLOCK(PREPROCESSOR_DETAIL_BLOCK); 956 1.1 joerg RECORD(PPD_MACRO_EXPANSION); 957 1.1 joerg RECORD(PPD_MACRO_DEFINITION); 958 1.1 joerg RECORD(PPD_INCLUSION_DIRECTIVE); 959 1.1 joerg 960 1.1 joerg // Decls and Types block. 961 1.1 joerg BLOCK(EXTENSION_BLOCK); 962 1.1 joerg RECORD(EXTENSION_METADATA); 963 1.1 joerg 964 1.1 joerg BLOCK(UNHASHED_CONTROL_BLOCK); 965 1.1 joerg RECORD(SIGNATURE); 966 1.1.1.2 joerg RECORD(AST_BLOCK_HASH); 967 1.1 joerg RECORD(DIAGNOSTIC_OPTIONS); 968 1.1 joerg RECORD(DIAG_PRAGMA_MAPPINGS); 969 1.1 joerg 970 1.1 joerg #undef RECORD 971 1.1 joerg #undef BLOCK 972 1.1 joerg Stream.ExitBlock(); 973 1.1 joerg } 974 1.1 joerg 975 1.1 joerg /// Prepares a path for being written to an AST file by converting it 976 1.1 joerg /// to an absolute path and removing nested './'s. 977 1.1 joerg /// 978 1.1 joerg /// \return \c true if the path was changed. 979 1.1 joerg static bool cleanPathForOutput(FileManager &FileMgr, 980 1.1 joerg SmallVectorImpl<char> &Path) { 981 1.1 joerg bool Changed = FileMgr.makeAbsolutePath(Path); 982 1.1 joerg return Changed | llvm::sys::path::remove_dots(Path); 983 1.1 joerg } 984 1.1 joerg 985 1.1 joerg /// Adjusts the given filename to only write out the portion of the 986 1.1 joerg /// filename that is not part of the system root directory. 987 1.1 joerg /// 988 1.1 joerg /// \param Filename the file name to adjust. 989 1.1 joerg /// 990 1.1 joerg /// \param BaseDir When non-NULL, the PCH file is a relocatable AST file and 991 1.1 joerg /// the returned filename will be adjusted by this root directory. 992 1.1 joerg /// 993 1.1 joerg /// \returns either the original filename (if it needs no adjustment) or the 994 1.1 joerg /// adjusted filename (which points into the @p Filename parameter). 995 1.1 joerg static const char * 996 1.1 joerg adjustFilenameForRelocatableAST(const char *Filename, StringRef BaseDir) { 997 1.1 joerg assert(Filename && "No file name to adjust?"); 998 1.1 joerg 999 1.1 joerg if (BaseDir.empty()) 1000 1.1 joerg return Filename; 1001 1.1 joerg 1002 1.1 joerg // Verify that the filename and the system root have the same prefix. 1003 1.1 joerg unsigned Pos = 0; 1004 1.1 joerg for (; Filename[Pos] && Pos < BaseDir.size(); ++Pos) 1005 1.1 joerg if (Filename[Pos] != BaseDir[Pos]) 1006 1.1 joerg return Filename; // Prefixes don't match. 1007 1.1 joerg 1008 1.1 joerg // We hit the end of the filename before we hit the end of the system root. 1009 1.1 joerg if (!Filename[Pos]) 1010 1.1 joerg return Filename; 1011 1.1 joerg 1012 1.1 joerg // If there's not a path separator at the end of the base directory nor 1013 1.1 joerg // immediately after it, then this isn't within the base directory. 1014 1.1 joerg if (!llvm::sys::path::is_separator(Filename[Pos])) { 1015 1.1 joerg if (!llvm::sys::path::is_separator(BaseDir.back())) 1016 1.1 joerg return Filename; 1017 1.1 joerg } else { 1018 1.1 joerg // If the file name has a '/' at the current position, skip over the '/'. 1019 1.1 joerg // We distinguish relative paths from absolute paths by the 1020 1.1 joerg // absence of '/' at the beginning of relative paths. 1021 1.1 joerg // 1022 1.1 joerg // FIXME: This is wrong. We distinguish them by asking if the path is 1023 1.1 joerg // absolute, which isn't the same thing. And there might be multiple '/'s 1024 1.1 joerg // in a row. Use a better mechanism to indicate whether we have emitted an 1025 1.1 joerg // absolute or relative path. 1026 1.1 joerg ++Pos; 1027 1.1 joerg } 1028 1.1 joerg 1029 1.1 joerg return Filename + Pos; 1030 1.1 joerg } 1031 1.1 joerg 1032 1.1.1.2 joerg std::pair<ASTFileSignature, ASTFileSignature> 1033 1.1.1.2 joerg ASTWriter::createSignature(StringRef AllBytes, StringRef ASTBlockBytes) { 1034 1.1 joerg llvm::SHA1 Hasher; 1035 1.1.1.2 joerg Hasher.update(ASTBlockBytes); 1036 1.1 joerg auto Hash = Hasher.result(); 1037 1.1.1.2 joerg ASTFileSignature ASTBlockHash = ASTFileSignature::create(Hash); 1038 1.1 joerg 1039 1.1.1.2 joerg // Add the remaining bytes (i.e. bytes before the unhashed control block that 1040 1.1.1.2 joerg // are not part of the AST block). 1041 1.1.1.2 joerg Hasher.update( 1042 1.1.1.2 joerg AllBytes.take_front(ASTBlockBytes.bytes_end() - AllBytes.bytes_begin())); 1043 1.1.1.2 joerg Hasher.update( 1044 1.1.1.2 joerg AllBytes.take_back(AllBytes.bytes_end() - ASTBlockBytes.bytes_end())); 1045 1.1.1.2 joerg Hash = Hasher.result(); 1046 1.1.1.2 joerg ASTFileSignature Signature = ASTFileSignature::create(Hash); 1047 1.1 joerg 1048 1.1.1.2 joerg return std::make_pair(ASTBlockHash, Signature); 1049 1.1 joerg } 1050 1.1 joerg 1051 1.1 joerg ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP, 1052 1.1 joerg ASTContext &Context) { 1053 1.1 joerg // Flush first to prepare the PCM hash (signature). 1054 1.1 joerg Stream.FlushToWord(); 1055 1.1 joerg auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3; 1056 1.1 joerg 1057 1.1 joerg // Enter the block and prepare to write records. 1058 1.1 joerg RecordData Record; 1059 1.1 joerg Stream.EnterSubblock(UNHASHED_CONTROL_BLOCK_ID, 5); 1060 1.1 joerg 1061 1.1 joerg // For implicit modules, write the hash of the PCM as its signature. 1062 1.1 joerg ASTFileSignature Signature; 1063 1.1 joerg if (WritingModule && 1064 1.1 joerg PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) { 1065 1.1.1.2 joerg ASTFileSignature ASTBlockHash; 1066 1.1.1.2 joerg auto ASTBlockStartByte = ASTBlockRange.first >> 3; 1067 1.1.1.2 joerg auto ASTBlockByteLength = (ASTBlockRange.second >> 3) - ASTBlockStartByte; 1068 1.1.1.2 joerg std::tie(ASTBlockHash, Signature) = createSignature( 1069 1.1.1.2 joerg StringRef(Buffer.begin(), StartOfUnhashedControl), 1070 1.1.1.2 joerg StringRef(Buffer.begin() + ASTBlockStartByte, ASTBlockByteLength)); 1071 1.1.1.2 joerg 1072 1.1.1.2 joerg Record.append(ASTBlockHash.begin(), ASTBlockHash.end()); 1073 1.1.1.2 joerg Stream.EmitRecord(AST_BLOCK_HASH, Record); 1074 1.1.1.2 joerg Record.clear(); 1075 1.1 joerg Record.append(Signature.begin(), Signature.end()); 1076 1.1 joerg Stream.EmitRecord(SIGNATURE, Record); 1077 1.1 joerg Record.clear(); 1078 1.1 joerg } 1079 1.1 joerg 1080 1.1 joerg // Diagnostic options. 1081 1.1 joerg const auto &Diags = Context.getDiagnostics(); 1082 1.1 joerg const DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions(); 1083 1.1 joerg #define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name); 1084 1.1 joerg #define ENUM_DIAGOPT(Name, Type, Bits, Default) \ 1085 1.1 joerg Record.push_back(static_cast<unsigned>(DiagOpts.get##Name())); 1086 1.1 joerg #include "clang/Basic/DiagnosticOptions.def" 1087 1.1 joerg Record.push_back(DiagOpts.Warnings.size()); 1088 1.1 joerg for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I) 1089 1.1 joerg AddString(DiagOpts.Warnings[I], Record); 1090 1.1 joerg Record.push_back(DiagOpts.Remarks.size()); 1091 1.1 joerg for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I) 1092 1.1 joerg AddString(DiagOpts.Remarks[I], Record); 1093 1.1 joerg // Note: we don't serialize the log or serialization file names, because they 1094 1.1 joerg // are generally transient files and will almost always be overridden. 1095 1.1 joerg Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record); 1096 1.1 joerg 1097 1.1 joerg // Write out the diagnostic/pragma mappings. 1098 1.1 joerg WritePragmaDiagnosticMappings(Diags, /* isModule = */ WritingModule); 1099 1.1 joerg 1100 1.1 joerg // Leave the options block. 1101 1.1 joerg Stream.ExitBlock(); 1102 1.1 joerg return Signature; 1103 1.1 joerg } 1104 1.1 joerg 1105 1.1 joerg /// Write the control block. 1106 1.1 joerg void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, 1107 1.1 joerg StringRef isysroot, 1108 1.1 joerg const std::string &OutputFile) { 1109 1.1 joerg using namespace llvm; 1110 1.1 joerg 1111 1.1 joerg Stream.EnterSubblock(CONTROL_BLOCK_ID, 5); 1112 1.1 joerg RecordData Record; 1113 1.1 joerg 1114 1.1 joerg // Metadata 1115 1.1 joerg auto MetadataAbbrev = std::make_shared<BitCodeAbbrev>(); 1116 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(METADATA)); 1117 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Major 1118 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Minor 1119 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang maj. 1120 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang min. 1121 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable 1122 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Timestamps 1123 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Errors 1124 1.1 joerg MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag 1125 1.1 joerg unsigned MetadataAbbrevCode = Stream.EmitAbbrev(std::move(MetadataAbbrev)); 1126 1.1 joerg assert((!WritingModule || isysroot.empty()) && 1127 1.1 joerg "writing module as a relocatable PCH?"); 1128 1.1 joerg { 1129 1.1 joerg RecordData::value_type Record[] = { 1130 1.1 joerg METADATA, 1131 1.1 joerg VERSION_MAJOR, 1132 1.1 joerg VERSION_MINOR, 1133 1.1 joerg CLANG_VERSION_MAJOR, 1134 1.1 joerg CLANG_VERSION_MINOR, 1135 1.1 joerg !isysroot.empty(), 1136 1.1 joerg IncludeTimestamps, 1137 1.1 joerg ASTHasCompilerErrors}; 1138 1.1 joerg Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record, 1139 1.1 joerg getClangFullRepositoryVersion()); 1140 1.1 joerg } 1141 1.1 joerg 1142 1.1 joerg if (WritingModule) { 1143 1.1 joerg // Module name 1144 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1145 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME)); 1146 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 1147 1.1 joerg unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev)); 1148 1.1 joerg RecordData::value_type Record[] = {MODULE_NAME}; 1149 1.1 joerg Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name); 1150 1.1 joerg } 1151 1.1 joerg 1152 1.1 joerg if (WritingModule && WritingModule->Directory) { 1153 1.1 joerg SmallString<128> BaseDir(WritingModule->Directory->getName()); 1154 1.1 joerg cleanPathForOutput(Context.getSourceManager().getFileManager(), BaseDir); 1155 1.1 joerg 1156 1.1 joerg // If the home of the module is the current working directory, then we 1157 1.1 joerg // want to pick up the cwd of the build process loading the module, not 1158 1.1 joerg // our cwd, when we load this module. 1159 1.1 joerg if (!PP.getHeaderSearchInfo() 1160 1.1 joerg .getHeaderSearchOpts() 1161 1.1 joerg .ModuleMapFileHomeIsCwd || 1162 1.1 joerg WritingModule->Directory->getName() != StringRef(".")) { 1163 1.1 joerg // Module directory. 1164 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1165 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY)); 1166 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory 1167 1.1 joerg unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev)); 1168 1.1 joerg 1169 1.1 joerg RecordData::value_type Record[] = {MODULE_DIRECTORY}; 1170 1.1 joerg Stream.EmitRecordWithBlob(AbbrevCode, Record, BaseDir); 1171 1.1 joerg } 1172 1.1 joerg 1173 1.1 joerg // Write out all other paths relative to the base directory if possible. 1174 1.1 joerg BaseDirectory.assign(BaseDir.begin(), BaseDir.end()); 1175 1.1 joerg } else if (!isysroot.empty()) { 1176 1.1 joerg // Write out paths relative to the sysroot if possible. 1177 1.1.1.2 joerg BaseDirectory = std::string(isysroot); 1178 1.1 joerg } 1179 1.1 joerg 1180 1.1 joerg // Module map file 1181 1.1 joerg if (WritingModule && WritingModule->Kind == Module::ModuleMapModule) { 1182 1.1 joerg Record.clear(); 1183 1.1 joerg 1184 1.1 joerg auto &Map = PP.getHeaderSearchInfo().getModuleMap(); 1185 1.1 joerg AddPath(WritingModule->PresumedModuleMapFile.empty() 1186 1.1 joerg ? Map.getModuleMapFileForUniquing(WritingModule)->getName() 1187 1.1 joerg : StringRef(WritingModule->PresumedModuleMapFile), 1188 1.1 joerg Record); 1189 1.1 joerg 1190 1.1 joerg // Additional module map files. 1191 1.1 joerg if (auto *AdditionalModMaps = 1192 1.1 joerg Map.getAdditionalModuleMapFiles(WritingModule)) { 1193 1.1 joerg Record.push_back(AdditionalModMaps->size()); 1194 1.1 joerg for (const FileEntry *F : *AdditionalModMaps) 1195 1.1 joerg AddPath(F->getName(), Record); 1196 1.1 joerg } else { 1197 1.1 joerg Record.push_back(0); 1198 1.1 joerg } 1199 1.1 joerg 1200 1.1 joerg Stream.EmitRecord(MODULE_MAP_FILE, Record); 1201 1.1 joerg } 1202 1.1 joerg 1203 1.1 joerg // Imports 1204 1.1 joerg if (Chain) { 1205 1.1 joerg serialization::ModuleManager &Mgr = Chain->getModuleManager(); 1206 1.1 joerg Record.clear(); 1207 1.1 joerg 1208 1.1 joerg for (ModuleFile &M : Mgr) { 1209 1.1 joerg // Skip modules that weren't directly imported. 1210 1.1 joerg if (!M.isDirectlyImported()) 1211 1.1 joerg continue; 1212 1.1 joerg 1213 1.1 joerg Record.push_back((unsigned)M.Kind); // FIXME: Stable encoding 1214 1.1 joerg AddSourceLocation(M.ImportLoc, Record); 1215 1.1 joerg 1216 1.1 joerg // If we have calculated signature, there is no need to store 1217 1.1 joerg // the size or timestamp. 1218 1.1 joerg Record.push_back(M.Signature ? 0 : M.File->getSize()); 1219 1.1 joerg Record.push_back(M.Signature ? 0 : getTimestampForOutput(M.File)); 1220 1.1 joerg 1221 1.1 joerg for (auto I : M.Signature) 1222 1.1 joerg Record.push_back(I); 1223 1.1 joerg 1224 1.1 joerg AddString(M.ModuleName, Record); 1225 1.1 joerg AddPath(M.FileName, Record); 1226 1.1 joerg } 1227 1.1 joerg Stream.EmitRecord(IMPORTS, Record); 1228 1.1 joerg } 1229 1.1 joerg 1230 1.1 joerg // Write the options block. 1231 1.1 joerg Stream.EnterSubblock(OPTIONS_BLOCK_ID, 4); 1232 1.1 joerg 1233 1.1 joerg // Language options. 1234 1.1 joerg Record.clear(); 1235 1.1 joerg const LangOptions &LangOpts = Context.getLangOpts(); 1236 1.1 joerg #define LANGOPT(Name, Bits, Default, Description) \ 1237 1.1 joerg Record.push_back(LangOpts.Name); 1238 1.1 joerg #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ 1239 1.1 joerg Record.push_back(static_cast<unsigned>(LangOpts.get##Name())); 1240 1.1 joerg #include "clang/Basic/LangOptions.def" 1241 1.1 joerg #define SANITIZER(NAME, ID) \ 1242 1.1 joerg Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID)); 1243 1.1 joerg #include "clang/Basic/Sanitizers.def" 1244 1.1 joerg 1245 1.1 joerg Record.push_back(LangOpts.ModuleFeatures.size()); 1246 1.1 joerg for (StringRef Feature : LangOpts.ModuleFeatures) 1247 1.1 joerg AddString(Feature, Record); 1248 1.1 joerg 1249 1.1 joerg Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind()); 1250 1.1 joerg AddVersionTuple(LangOpts.ObjCRuntime.getVersion(), Record); 1251 1.1 joerg 1252 1.1 joerg AddString(LangOpts.CurrentModule, Record); 1253 1.1 joerg 1254 1.1 joerg // Comment options. 1255 1.1 joerg Record.push_back(LangOpts.CommentOpts.BlockCommandNames.size()); 1256 1.1 joerg for (const auto &I : LangOpts.CommentOpts.BlockCommandNames) { 1257 1.1 joerg AddString(I, Record); 1258 1.1 joerg } 1259 1.1 joerg Record.push_back(LangOpts.CommentOpts.ParseAllComments); 1260 1.1 joerg 1261 1.1 joerg // OpenMP offloading options. 1262 1.1 joerg Record.push_back(LangOpts.OMPTargetTriples.size()); 1263 1.1 joerg for (auto &T : LangOpts.OMPTargetTriples) 1264 1.1 joerg AddString(T.getTriple(), Record); 1265 1.1 joerg 1266 1.1 joerg AddString(LangOpts.OMPHostIRFile, Record); 1267 1.1 joerg 1268 1.1 joerg Stream.EmitRecord(LANGUAGE_OPTIONS, Record); 1269 1.1 joerg 1270 1.1 joerg // Target options. 1271 1.1 joerg Record.clear(); 1272 1.1 joerg const TargetInfo &Target = Context.getTargetInfo(); 1273 1.1 joerg const TargetOptions &TargetOpts = Target.getTargetOpts(); 1274 1.1 joerg AddString(TargetOpts.Triple, Record); 1275 1.1 joerg AddString(TargetOpts.CPU, Record); 1276 1.1.1.2 joerg AddString(TargetOpts.TuneCPU, Record); 1277 1.1 joerg AddString(TargetOpts.ABI, Record); 1278 1.1 joerg Record.push_back(TargetOpts.FeaturesAsWritten.size()); 1279 1.1 joerg for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); I != N; ++I) { 1280 1.1 joerg AddString(TargetOpts.FeaturesAsWritten[I], Record); 1281 1.1 joerg } 1282 1.1 joerg Record.push_back(TargetOpts.Features.size()); 1283 1.1 joerg for (unsigned I = 0, N = TargetOpts.Features.size(); I != N; ++I) { 1284 1.1 joerg AddString(TargetOpts.Features[I], Record); 1285 1.1 joerg } 1286 1.1 joerg Stream.EmitRecord(TARGET_OPTIONS, Record); 1287 1.1 joerg 1288 1.1 joerg // File system options. 1289 1.1 joerg Record.clear(); 1290 1.1 joerg const FileSystemOptions &FSOpts = 1291 1.1 joerg Context.getSourceManager().getFileManager().getFileSystemOpts(); 1292 1.1 joerg AddString(FSOpts.WorkingDir, Record); 1293 1.1 joerg Stream.EmitRecord(FILE_SYSTEM_OPTIONS, Record); 1294 1.1 joerg 1295 1.1 joerg // Header search options. 1296 1.1 joerg Record.clear(); 1297 1.1 joerg const HeaderSearchOptions &HSOpts 1298 1.1 joerg = PP.getHeaderSearchInfo().getHeaderSearchOpts(); 1299 1.1 joerg AddString(HSOpts.Sysroot, Record); 1300 1.1 joerg 1301 1.1 joerg // Include entries. 1302 1.1 joerg Record.push_back(HSOpts.UserEntries.size()); 1303 1.1 joerg for (unsigned I = 0, N = HSOpts.UserEntries.size(); I != N; ++I) { 1304 1.1 joerg const HeaderSearchOptions::Entry &Entry = HSOpts.UserEntries[I]; 1305 1.1 joerg AddString(Entry.Path, Record); 1306 1.1 joerg Record.push_back(static_cast<unsigned>(Entry.Group)); 1307 1.1 joerg Record.push_back(Entry.IsFramework); 1308 1.1 joerg Record.push_back(Entry.IgnoreSysRoot); 1309 1.1 joerg } 1310 1.1 joerg 1311 1.1 joerg // System header prefixes. 1312 1.1 joerg Record.push_back(HSOpts.SystemHeaderPrefixes.size()); 1313 1.1 joerg for (unsigned I = 0, N = HSOpts.SystemHeaderPrefixes.size(); I != N; ++I) { 1314 1.1 joerg AddString(HSOpts.SystemHeaderPrefixes[I].Prefix, Record); 1315 1.1 joerg Record.push_back(HSOpts.SystemHeaderPrefixes[I].IsSystemHeader); 1316 1.1 joerg } 1317 1.1 joerg 1318 1.1 joerg AddString(HSOpts.ResourceDir, Record); 1319 1.1 joerg AddString(HSOpts.ModuleCachePath, Record); 1320 1.1 joerg AddString(HSOpts.ModuleUserBuildPath, Record); 1321 1.1 joerg Record.push_back(HSOpts.DisableModuleHash); 1322 1.1 joerg Record.push_back(HSOpts.ImplicitModuleMaps); 1323 1.1 joerg Record.push_back(HSOpts.ModuleMapFileHomeIsCwd); 1324 1.1.1.2 joerg Record.push_back(HSOpts.EnablePrebuiltImplicitModules); 1325 1.1 joerg Record.push_back(HSOpts.UseBuiltinIncludes); 1326 1.1 joerg Record.push_back(HSOpts.UseStandardSystemIncludes); 1327 1.1 joerg Record.push_back(HSOpts.UseStandardCXXIncludes); 1328 1.1 joerg Record.push_back(HSOpts.UseLibcxx); 1329 1.1 joerg // Write out the specific module cache path that contains the module files. 1330 1.1 joerg AddString(PP.getHeaderSearchInfo().getModuleCachePath(), Record); 1331 1.1 joerg Stream.EmitRecord(HEADER_SEARCH_OPTIONS, Record); 1332 1.1 joerg 1333 1.1 joerg // Preprocessor options. 1334 1.1 joerg Record.clear(); 1335 1.1 joerg const PreprocessorOptions &PPOpts = PP.getPreprocessorOpts(); 1336 1.1 joerg 1337 1.1 joerg // Macro definitions. 1338 1.1 joerg Record.push_back(PPOpts.Macros.size()); 1339 1.1 joerg for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) { 1340 1.1 joerg AddString(PPOpts.Macros[I].first, Record); 1341 1.1 joerg Record.push_back(PPOpts.Macros[I].second); 1342 1.1 joerg } 1343 1.1 joerg 1344 1.1 joerg // Includes 1345 1.1 joerg Record.push_back(PPOpts.Includes.size()); 1346 1.1 joerg for (unsigned I = 0, N = PPOpts.Includes.size(); I != N; ++I) 1347 1.1 joerg AddString(PPOpts.Includes[I], Record); 1348 1.1 joerg 1349 1.1 joerg // Macro includes 1350 1.1 joerg Record.push_back(PPOpts.MacroIncludes.size()); 1351 1.1 joerg for (unsigned I = 0, N = PPOpts.MacroIncludes.size(); I != N; ++I) 1352 1.1 joerg AddString(PPOpts.MacroIncludes[I], Record); 1353 1.1 joerg 1354 1.1 joerg Record.push_back(PPOpts.UsePredefines); 1355 1.1 joerg // Detailed record is important since it is used for the module cache hash. 1356 1.1 joerg Record.push_back(PPOpts.DetailedRecord); 1357 1.1 joerg AddString(PPOpts.ImplicitPCHInclude, Record); 1358 1.1 joerg Record.push_back(static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary)); 1359 1.1 joerg Stream.EmitRecord(PREPROCESSOR_OPTIONS, Record); 1360 1.1 joerg 1361 1.1 joerg // Leave the options block. 1362 1.1 joerg Stream.ExitBlock(); 1363 1.1 joerg 1364 1.1 joerg // Original file name and file ID 1365 1.1 joerg SourceManager &SM = Context.getSourceManager(); 1366 1.1 joerg if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { 1367 1.1 joerg auto FileAbbrev = std::make_shared<BitCodeAbbrev>(); 1368 1.1 joerg FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE)); 1369 1.1 joerg FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // File ID 1370 1.1 joerg FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 1371 1.1 joerg unsigned FileAbbrevCode = Stream.EmitAbbrev(std::move(FileAbbrev)); 1372 1.1 joerg 1373 1.1 joerg Record.clear(); 1374 1.1 joerg Record.push_back(ORIGINAL_FILE); 1375 1.1 joerg Record.push_back(SM.getMainFileID().getOpaqueValue()); 1376 1.1 joerg EmitRecordWithPath(FileAbbrevCode, Record, MainFile->getName()); 1377 1.1 joerg } 1378 1.1 joerg 1379 1.1 joerg Record.clear(); 1380 1.1 joerg Record.push_back(SM.getMainFileID().getOpaqueValue()); 1381 1.1 joerg Stream.EmitRecord(ORIGINAL_FILE_ID, Record); 1382 1.1 joerg 1383 1.1 joerg // Original PCH directory 1384 1.1 joerg if (!OutputFile.empty() && OutputFile != "-") { 1385 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1386 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR)); 1387 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 1388 1.1 joerg unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev)); 1389 1.1 joerg 1390 1.1 joerg SmallString<128> OutputPath(OutputFile); 1391 1.1 joerg 1392 1.1 joerg SM.getFileManager().makeAbsolutePath(OutputPath); 1393 1.1 joerg StringRef origDir = llvm::sys::path::parent_path(OutputPath); 1394 1.1 joerg 1395 1.1 joerg RecordData::value_type Record[] = {ORIGINAL_PCH_DIR}; 1396 1.1 joerg Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir); 1397 1.1 joerg } 1398 1.1 joerg 1399 1.1 joerg WriteInputFiles(Context.SourceMgr, 1400 1.1 joerg PP.getHeaderSearchInfo().getHeaderSearchOpts(), 1401 1.1 joerg PP.getLangOpts().Modules); 1402 1.1 joerg Stream.ExitBlock(); 1403 1.1 joerg } 1404 1.1 joerg 1405 1.1 joerg namespace { 1406 1.1 joerg 1407 1.1 joerg /// An input file. 1408 1.1 joerg struct InputFileEntry { 1409 1.1 joerg const FileEntry *File; 1410 1.1 joerg bool IsSystemFile; 1411 1.1 joerg bool IsTransient; 1412 1.1 joerg bool BufferOverridden; 1413 1.1 joerg bool IsTopLevelModuleMap; 1414 1.1 joerg uint32_t ContentHash[2]; 1415 1.1 joerg }; 1416 1.1 joerg 1417 1.1 joerg } // namespace 1418 1.1 joerg 1419 1.1 joerg void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, 1420 1.1 joerg HeaderSearchOptions &HSOpts, 1421 1.1 joerg bool Modules) { 1422 1.1 joerg using namespace llvm; 1423 1.1 joerg 1424 1.1 joerg Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4); 1425 1.1 joerg 1426 1.1 joerg // Create input-file abbreviation. 1427 1.1 joerg auto IFAbbrev = std::make_shared<BitCodeAbbrev>(); 1428 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE)); 1429 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID 1430 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size 1431 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time 1432 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Overridden 1433 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Transient 1434 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Module map 1435 1.1 joerg IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name 1436 1.1 joerg unsigned IFAbbrevCode = Stream.EmitAbbrev(std::move(IFAbbrev)); 1437 1.1 joerg 1438 1.1 joerg // Create input file hash abbreviation. 1439 1.1 joerg auto IFHAbbrev = std::make_shared<BitCodeAbbrev>(); 1440 1.1 joerg IFHAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE_HASH)); 1441 1.1 joerg IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1442 1.1 joerg IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1443 1.1 joerg unsigned IFHAbbrevCode = Stream.EmitAbbrev(std::move(IFHAbbrev)); 1444 1.1 joerg 1445 1.1 joerg // Get all ContentCache objects for files, sorted by whether the file is a 1446 1.1 joerg // system one or not. System files go at the back, users files at the front. 1447 1.1 joerg std::deque<InputFileEntry> SortedFiles; 1448 1.1 joerg for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) { 1449 1.1 joerg // Get this source location entry. 1450 1.1 joerg const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I); 1451 1.1 joerg assert(&SourceMgr.getSLocEntry(FileID::get(I)) == SLoc); 1452 1.1 joerg 1453 1.1 joerg // We only care about file entries that were not overridden. 1454 1.1 joerg if (!SLoc->isFile()) 1455 1.1 joerg continue; 1456 1.1 joerg const SrcMgr::FileInfo &File = SLoc->getFile(); 1457 1.1.1.2 joerg const SrcMgr::ContentCache *Cache = &File.getContentCache(); 1458 1.1 joerg if (!Cache->OrigEntry) 1459 1.1 joerg continue; 1460 1.1 joerg 1461 1.1 joerg InputFileEntry Entry; 1462 1.1 joerg Entry.File = Cache->OrigEntry; 1463 1.1 joerg Entry.IsSystemFile = isSystem(File.getFileCharacteristic()); 1464 1.1 joerg Entry.IsTransient = Cache->IsTransient; 1465 1.1 joerg Entry.BufferOverridden = Cache->BufferOverridden; 1466 1.1 joerg Entry.IsTopLevelModuleMap = isModuleMap(File.getFileCharacteristic()) && 1467 1.1 joerg File.getIncludeLoc().isInvalid(); 1468 1.1 joerg 1469 1.1 joerg auto ContentHash = hash_code(-1); 1470 1.1 joerg if (PP->getHeaderSearchInfo() 1471 1.1 joerg .getHeaderSearchOpts() 1472 1.1 joerg .ValidateASTInputFilesContent) { 1473 1.1.1.2 joerg auto MemBuff = Cache->getBufferIfLoaded(); 1474 1.1 joerg if (MemBuff) 1475 1.1 joerg ContentHash = hash_value(MemBuff->getBuffer()); 1476 1.1 joerg else 1477 1.1 joerg // FIXME: The path should be taken from the FileEntryRef. 1478 1.1 joerg PP->Diag(SourceLocation(), diag::err_module_unable_to_hash_content) 1479 1.1 joerg << Entry.File->getName(); 1480 1.1 joerg } 1481 1.1 joerg auto CH = llvm::APInt(64, ContentHash); 1482 1.1 joerg Entry.ContentHash[0] = 1483 1.1 joerg static_cast<uint32_t>(CH.getLoBits(32).getZExtValue()); 1484 1.1 joerg Entry.ContentHash[1] = 1485 1.1 joerg static_cast<uint32_t>(CH.getHiBits(32).getZExtValue()); 1486 1.1 joerg 1487 1.1 joerg if (Entry.IsSystemFile) 1488 1.1 joerg SortedFiles.push_back(Entry); 1489 1.1 joerg else 1490 1.1 joerg SortedFiles.push_front(Entry); 1491 1.1 joerg } 1492 1.1 joerg 1493 1.1 joerg unsigned UserFilesNum = 0; 1494 1.1 joerg // Write out all of the input files. 1495 1.1 joerg std::vector<uint64_t> InputFileOffsets; 1496 1.1 joerg for (const auto &Entry : SortedFiles) { 1497 1.1 joerg uint32_t &InputFileID = InputFileIDs[Entry.File]; 1498 1.1 joerg if (InputFileID != 0) 1499 1.1 joerg continue; // already recorded this file. 1500 1.1 joerg 1501 1.1 joerg // Record this entry's offset. 1502 1.1 joerg InputFileOffsets.push_back(Stream.GetCurrentBitNo()); 1503 1.1 joerg 1504 1.1 joerg InputFileID = InputFileOffsets.size(); 1505 1.1 joerg 1506 1.1 joerg if (!Entry.IsSystemFile) 1507 1.1 joerg ++UserFilesNum; 1508 1.1 joerg 1509 1.1 joerg // Emit size/modification time for this file. 1510 1.1 joerg // And whether this file was overridden. 1511 1.1 joerg { 1512 1.1 joerg RecordData::value_type Record[] = { 1513 1.1 joerg INPUT_FILE, 1514 1.1 joerg InputFileOffsets.size(), 1515 1.1 joerg (uint64_t)Entry.File->getSize(), 1516 1.1 joerg (uint64_t)getTimestampForOutput(Entry.File), 1517 1.1 joerg Entry.BufferOverridden, 1518 1.1 joerg Entry.IsTransient, 1519 1.1 joerg Entry.IsTopLevelModuleMap}; 1520 1.1 joerg 1521 1.1 joerg // FIXME: The path should be taken from the FileEntryRef. 1522 1.1 joerg EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName()); 1523 1.1 joerg } 1524 1.1 joerg 1525 1.1 joerg // Emit content hash for this file. 1526 1.1 joerg { 1527 1.1 joerg RecordData::value_type Record[] = {INPUT_FILE_HASH, Entry.ContentHash[0], 1528 1.1 joerg Entry.ContentHash[1]}; 1529 1.1 joerg Stream.EmitRecordWithAbbrev(IFHAbbrevCode, Record); 1530 1.1 joerg } 1531 1.1 joerg } 1532 1.1 joerg 1533 1.1 joerg Stream.ExitBlock(); 1534 1.1 joerg 1535 1.1 joerg // Create input file offsets abbreviation. 1536 1.1 joerg auto OffsetsAbbrev = std::make_shared<BitCodeAbbrev>(); 1537 1.1 joerg OffsetsAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE_OFFSETS)); 1538 1.1 joerg OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # input files 1539 1.1 joerg OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # non-system 1540 1.1 joerg // input files 1541 1.1 joerg OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Array 1542 1.1 joerg unsigned OffsetsAbbrevCode = Stream.EmitAbbrev(std::move(OffsetsAbbrev)); 1543 1.1 joerg 1544 1.1 joerg // Write input file offsets. 1545 1.1 joerg RecordData::value_type Record[] = {INPUT_FILE_OFFSETS, 1546 1.1 joerg InputFileOffsets.size(), UserFilesNum}; 1547 1.1 joerg Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, bytes(InputFileOffsets)); 1548 1.1 joerg } 1549 1.1 joerg 1550 1.1 joerg //===----------------------------------------------------------------------===// 1551 1.1 joerg // Source Manager Serialization 1552 1.1 joerg //===----------------------------------------------------------------------===// 1553 1.1 joerg 1554 1.1 joerg /// Create an abbreviation for the SLocEntry that refers to a 1555 1.1 joerg /// file. 1556 1.1 joerg static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { 1557 1.1 joerg using namespace llvm; 1558 1.1 joerg 1559 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1560 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY)); 1561 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1562 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 1563 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic 1564 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1565 1.1 joerg // FileEntry fields. 1566 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Input File ID 1567 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs 1568 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24)); // FirstDeclIndex 1569 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumDecls 1570 1.1 joerg return Stream.EmitAbbrev(std::move(Abbrev)); 1571 1.1 joerg } 1572 1.1 joerg 1573 1.1 joerg /// Create an abbreviation for the SLocEntry that refers to a 1574 1.1 joerg /// buffer. 1575 1.1 joerg static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { 1576 1.1 joerg using namespace llvm; 1577 1.1 joerg 1578 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1579 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY)); 1580 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1581 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location 1582 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic 1583 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives 1584 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob 1585 1.1 joerg return Stream.EmitAbbrev(std::move(Abbrev)); 1586 1.1 joerg } 1587 1.1 joerg 1588 1.1 joerg /// Create an abbreviation for the SLocEntry that refers to a 1589 1.1 joerg /// buffer's blob. 1590 1.1 joerg static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream, 1591 1.1 joerg bool Compressed) { 1592 1.1 joerg using namespace llvm; 1593 1.1 joerg 1594 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1595 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(Compressed ? SM_SLOC_BUFFER_BLOB_COMPRESSED 1596 1.1 joerg : SM_SLOC_BUFFER_BLOB)); 1597 1.1 joerg if (Compressed) 1598 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Uncompressed size 1599 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob 1600 1.1 joerg return Stream.EmitAbbrev(std::move(Abbrev)); 1601 1.1 joerg } 1602 1.1 joerg 1603 1.1 joerg /// Create an abbreviation for the SLocEntry that refers to a macro 1604 1.1 joerg /// expansion. 1605 1.1 joerg static unsigned CreateSLocExpansionAbbrev(llvm::BitstreamWriter &Stream) { 1606 1.1 joerg using namespace llvm; 1607 1.1 joerg 1608 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1609 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_EXPANSION_ENTRY)); 1610 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset 1611 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location 1612 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location 1613 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location 1614 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is token range 1615 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length 1616 1.1 joerg return Stream.EmitAbbrev(std::move(Abbrev)); 1617 1.1 joerg } 1618 1.1 joerg 1619 1.1.1.2 joerg /// Emit key length and data length as ULEB-encoded data, and return them as a 1620 1.1.1.2 joerg /// pair. 1621 1.1.1.2 joerg static std::pair<unsigned, unsigned> 1622 1.1.1.2 joerg emitULEBKeyDataLength(unsigned KeyLen, unsigned DataLen, raw_ostream &Out) { 1623 1.1.1.2 joerg llvm::encodeULEB128(KeyLen, Out); 1624 1.1.1.2 joerg llvm::encodeULEB128(DataLen, Out); 1625 1.1.1.2 joerg return std::make_pair(KeyLen, DataLen); 1626 1.1.1.2 joerg } 1627 1.1.1.2 joerg 1628 1.1 joerg namespace { 1629 1.1 joerg 1630 1.1 joerg // Trait used for the on-disk hash table of header search information. 1631 1.1 joerg class HeaderFileInfoTrait { 1632 1.1 joerg ASTWriter &Writer; 1633 1.1 joerg 1634 1.1 joerg // Keep track of the framework names we've used during serialization. 1635 1.1.1.2 joerg SmallString<128> FrameworkStringData; 1636 1.1 joerg llvm::StringMap<unsigned> FrameworkNameOffset; 1637 1.1 joerg 1638 1.1 joerg public: 1639 1.1 joerg HeaderFileInfoTrait(ASTWriter &Writer) : Writer(Writer) {} 1640 1.1 joerg 1641 1.1 joerg struct key_type { 1642 1.1 joerg StringRef Filename; 1643 1.1 joerg off_t Size; 1644 1.1 joerg time_t ModTime; 1645 1.1 joerg }; 1646 1.1 joerg using key_type_ref = const key_type &; 1647 1.1 joerg 1648 1.1 joerg using UnresolvedModule = 1649 1.1 joerg llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>; 1650 1.1 joerg 1651 1.1 joerg struct data_type { 1652 1.1 joerg const HeaderFileInfo &HFI; 1653 1.1 joerg ArrayRef<ModuleMap::KnownHeader> KnownHeaders; 1654 1.1 joerg UnresolvedModule Unresolved; 1655 1.1 joerg }; 1656 1.1 joerg using data_type_ref = const data_type &; 1657 1.1 joerg 1658 1.1 joerg using hash_value_type = unsigned; 1659 1.1 joerg using offset_type = unsigned; 1660 1.1 joerg 1661 1.1 joerg hash_value_type ComputeHash(key_type_ref key) { 1662 1.1 joerg // The hash is based only on size/time of the file, so that the reader can 1663 1.1 joerg // match even when symlinking or excess path elements ("foo/../", "../") 1664 1.1 joerg // change the form of the name. However, complete path is still the key. 1665 1.1 joerg return llvm::hash_combine(key.Size, key.ModTime); 1666 1.1 joerg } 1667 1.1 joerg 1668 1.1 joerg std::pair<unsigned, unsigned> 1669 1.1 joerg EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) { 1670 1.1 joerg unsigned KeyLen = key.Filename.size() + 1 + 8 + 8; 1671 1.1 joerg unsigned DataLen = 1 + 2 + 4 + 4; 1672 1.1 joerg for (auto ModInfo : Data.KnownHeaders) 1673 1.1 joerg if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule())) 1674 1.1 joerg DataLen += 4; 1675 1.1 joerg if (Data.Unresolved.getPointer()) 1676 1.1 joerg DataLen += 4; 1677 1.1.1.2 joerg return emitULEBKeyDataLength(KeyLen, DataLen, Out); 1678 1.1 joerg } 1679 1.1 joerg 1680 1.1 joerg void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) { 1681 1.1 joerg using namespace llvm::support; 1682 1.1 joerg 1683 1.1 joerg endian::Writer LE(Out, little); 1684 1.1 joerg LE.write<uint64_t>(key.Size); 1685 1.1 joerg KeyLen -= 8; 1686 1.1 joerg LE.write<uint64_t>(key.ModTime); 1687 1.1 joerg KeyLen -= 8; 1688 1.1 joerg Out.write(key.Filename.data(), KeyLen); 1689 1.1 joerg } 1690 1.1 joerg 1691 1.1 joerg void EmitData(raw_ostream &Out, key_type_ref key, 1692 1.1 joerg data_type_ref Data, unsigned DataLen) { 1693 1.1 joerg using namespace llvm::support; 1694 1.1 joerg 1695 1.1 joerg endian::Writer LE(Out, little); 1696 1.1 joerg uint64_t Start = Out.tell(); (void)Start; 1697 1.1 joerg 1698 1.1 joerg unsigned char Flags = (Data.HFI.isImport << 5) 1699 1.1 joerg | (Data.HFI.isPragmaOnce << 4) 1700 1.1 joerg | (Data.HFI.DirInfo << 1) 1701 1.1 joerg | Data.HFI.IndexHeaderMapHeader; 1702 1.1 joerg LE.write<uint8_t>(Flags); 1703 1.1 joerg LE.write<uint16_t>(Data.HFI.NumIncludes); 1704 1.1 joerg 1705 1.1 joerg if (!Data.HFI.ControllingMacro) 1706 1.1 joerg LE.write<uint32_t>(Data.HFI.ControllingMacroID); 1707 1.1 joerg else 1708 1.1 joerg LE.write<uint32_t>(Writer.getIdentifierRef(Data.HFI.ControllingMacro)); 1709 1.1 joerg 1710 1.1 joerg unsigned Offset = 0; 1711 1.1 joerg if (!Data.HFI.Framework.empty()) { 1712 1.1 joerg // If this header refers into a framework, save the framework name. 1713 1.1 joerg llvm::StringMap<unsigned>::iterator Pos 1714 1.1 joerg = FrameworkNameOffset.find(Data.HFI.Framework); 1715 1.1 joerg if (Pos == FrameworkNameOffset.end()) { 1716 1.1 joerg Offset = FrameworkStringData.size() + 1; 1717 1.1.1.2 joerg FrameworkStringData.append(Data.HFI.Framework); 1718 1.1 joerg FrameworkStringData.push_back(0); 1719 1.1 joerg 1720 1.1 joerg FrameworkNameOffset[Data.HFI.Framework] = Offset; 1721 1.1 joerg } else 1722 1.1 joerg Offset = Pos->second; 1723 1.1 joerg } 1724 1.1 joerg LE.write<uint32_t>(Offset); 1725 1.1 joerg 1726 1.1 joerg auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) { 1727 1.1 joerg if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) { 1728 1.1 joerg uint32_t Value = (ModID << 2) | (unsigned)Role; 1729 1.1 joerg assert((Value >> 2) == ModID && "overflow in header module info"); 1730 1.1 joerg LE.write<uint32_t>(Value); 1731 1.1 joerg } 1732 1.1 joerg }; 1733 1.1 joerg 1734 1.1 joerg // FIXME: If the header is excluded, we should write out some 1735 1.1 joerg // record of that fact. 1736 1.1 joerg for (auto ModInfo : Data.KnownHeaders) 1737 1.1 joerg EmitModule(ModInfo.getModule(), ModInfo.getRole()); 1738 1.1 joerg if (Data.Unresolved.getPointer()) 1739 1.1 joerg EmitModule(Data.Unresolved.getPointer(), Data.Unresolved.getInt()); 1740 1.1 joerg 1741 1.1 joerg assert(Out.tell() - Start == DataLen && "Wrong data length"); 1742 1.1 joerg } 1743 1.1 joerg 1744 1.1 joerg const char *strings_begin() const { return FrameworkStringData.begin(); } 1745 1.1 joerg const char *strings_end() const { return FrameworkStringData.end(); } 1746 1.1 joerg }; 1747 1.1 joerg 1748 1.1 joerg } // namespace 1749 1.1 joerg 1750 1.1 joerg /// Write the header search block for the list of files that 1751 1.1 joerg /// 1752 1.1 joerg /// \param HS The header search structure to save. 1753 1.1 joerg void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { 1754 1.1 joerg HeaderFileInfoTrait GeneratorTrait(*this); 1755 1.1 joerg llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator; 1756 1.1 joerg SmallVector<const char *, 4> SavedStrings; 1757 1.1 joerg unsigned NumHeaderSearchEntries = 0; 1758 1.1 joerg 1759 1.1 joerg // Find all unresolved headers for the current module. We generally will 1760 1.1 joerg // have resolved them before we get here, but not necessarily: we might be 1761 1.1 joerg // compiling a preprocessed module, where there is no requirement for the 1762 1.1 joerg // original files to exist any more. 1763 1.1 joerg const HeaderFileInfo Empty; // So we can take a reference. 1764 1.1 joerg if (WritingModule) { 1765 1.1 joerg llvm::SmallVector<Module *, 16> Worklist(1, WritingModule); 1766 1.1 joerg while (!Worklist.empty()) { 1767 1.1 joerg Module *M = Worklist.pop_back_val(); 1768 1.1.1.2 joerg // We don't care about headers in unimportable submodules. 1769 1.1.1.2 joerg if (M->isUnimportable()) 1770 1.1 joerg continue; 1771 1.1 joerg 1772 1.1 joerg // Map to disk files where possible, to pick up any missing stat 1773 1.1 joerg // information. This also means we don't need to check the unresolved 1774 1.1 joerg // headers list when emitting resolved headers in the first loop below. 1775 1.1 joerg // FIXME: It'd be preferable to avoid doing this if we were given 1776 1.1 joerg // sufficient stat information in the module map. 1777 1.1 joerg HS.getModuleMap().resolveHeaderDirectives(M); 1778 1.1 joerg 1779 1.1 joerg // If the file didn't exist, we can still create a module if we were given 1780 1.1 joerg // enough information in the module map. 1781 1.1 joerg for (auto U : M->MissingHeaders) { 1782 1.1 joerg // Check that we were given enough information to build a module 1783 1.1 joerg // without this file existing on disk. 1784 1.1 joerg if (!U.Size || (!U.ModTime && IncludeTimestamps)) { 1785 1.1 joerg PP->Diag(U.FileNameLoc, diag::err_module_no_size_mtime_for_header) 1786 1.1 joerg << WritingModule->getFullModuleName() << U.Size.hasValue() 1787 1.1 joerg << U.FileName; 1788 1.1 joerg continue; 1789 1.1 joerg } 1790 1.1 joerg 1791 1.1 joerg // Form the effective relative pathname for the file. 1792 1.1 joerg SmallString<128> Filename(M->Directory->getName()); 1793 1.1 joerg llvm::sys::path::append(Filename, U.FileName); 1794 1.1 joerg PreparePathForOutput(Filename); 1795 1.1 joerg 1796 1.1 joerg StringRef FilenameDup = strdup(Filename.c_str()); 1797 1.1 joerg SavedStrings.push_back(FilenameDup.data()); 1798 1.1 joerg 1799 1.1 joerg HeaderFileInfoTrait::key_type Key = { 1800 1.1 joerg FilenameDup, *U.Size, IncludeTimestamps ? *U.ModTime : 0 1801 1.1 joerg }; 1802 1.1 joerg HeaderFileInfoTrait::data_type Data = { 1803 1.1 joerg Empty, {}, {M, ModuleMap::headerKindToRole(U.Kind)} 1804 1.1 joerg }; 1805 1.1 joerg // FIXME: Deal with cases where there are multiple unresolved header 1806 1.1 joerg // directives in different submodules for the same header. 1807 1.1 joerg Generator.insert(Key, Data, GeneratorTrait); 1808 1.1 joerg ++NumHeaderSearchEntries; 1809 1.1 joerg } 1810 1.1 joerg 1811 1.1 joerg Worklist.append(M->submodule_begin(), M->submodule_end()); 1812 1.1 joerg } 1813 1.1 joerg } 1814 1.1 joerg 1815 1.1 joerg SmallVector<const FileEntry *, 16> FilesByUID; 1816 1.1 joerg HS.getFileMgr().GetUniqueIDMapping(FilesByUID); 1817 1.1 joerg 1818 1.1 joerg if (FilesByUID.size() > HS.header_file_size()) 1819 1.1 joerg FilesByUID.resize(HS.header_file_size()); 1820 1.1 joerg 1821 1.1 joerg for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) { 1822 1.1 joerg const FileEntry *File = FilesByUID[UID]; 1823 1.1 joerg if (!File) 1824 1.1 joerg continue; 1825 1.1 joerg 1826 1.1 joerg // Get the file info. This will load info from the external source if 1827 1.1 joerg // necessary. Skip emitting this file if we have no information on it 1828 1.1 joerg // as a header file (in which case HFI will be null) or if it hasn't 1829 1.1 joerg // changed since it was loaded. Also skip it if it's for a modular header 1830 1.1 joerg // from a different module; in that case, we rely on the module(s) 1831 1.1 joerg // containing the header to provide this information. 1832 1.1 joerg const HeaderFileInfo *HFI = 1833 1.1 joerg HS.getExistingFileInfo(File, /*WantExternal*/!Chain); 1834 1.1 joerg if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader)) 1835 1.1 joerg continue; 1836 1.1 joerg 1837 1.1 joerg // Massage the file path into an appropriate form. 1838 1.1 joerg StringRef Filename = File->getName(); 1839 1.1 joerg SmallString<128> FilenameTmp(Filename); 1840 1.1 joerg if (PreparePathForOutput(FilenameTmp)) { 1841 1.1 joerg // If we performed any translation on the file name at all, we need to 1842 1.1 joerg // save this string, since the generator will refer to it later. 1843 1.1 joerg Filename = StringRef(strdup(FilenameTmp.c_str())); 1844 1.1 joerg SavedStrings.push_back(Filename.data()); 1845 1.1 joerg } 1846 1.1 joerg 1847 1.1 joerg HeaderFileInfoTrait::key_type Key = { 1848 1.1 joerg Filename, File->getSize(), getTimestampForOutput(File) 1849 1.1 joerg }; 1850 1.1 joerg HeaderFileInfoTrait::data_type Data = { 1851 1.1.1.2 joerg *HFI, HS.getModuleMap().findResolvedModulesForHeader(File), {} 1852 1.1 joerg }; 1853 1.1 joerg Generator.insert(Key, Data, GeneratorTrait); 1854 1.1 joerg ++NumHeaderSearchEntries; 1855 1.1 joerg } 1856 1.1 joerg 1857 1.1 joerg // Create the on-disk hash table in a buffer. 1858 1.1 joerg SmallString<4096> TableData; 1859 1.1 joerg uint32_t BucketOffset; 1860 1.1 joerg { 1861 1.1 joerg using namespace llvm::support; 1862 1.1 joerg 1863 1.1 joerg llvm::raw_svector_ostream Out(TableData); 1864 1.1 joerg // Make sure that no bucket is at offset 0 1865 1.1 joerg endian::write<uint32_t>(Out, 0, little); 1866 1.1 joerg BucketOffset = Generator.Emit(Out, GeneratorTrait); 1867 1.1 joerg } 1868 1.1 joerg 1869 1.1 joerg // Create a blob abbreviation 1870 1.1 joerg using namespace llvm; 1871 1.1 joerg 1872 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1873 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE)); 1874 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1875 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1876 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 1877 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 1878 1.1 joerg unsigned TableAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 1879 1.1 joerg 1880 1.1 joerg // Write the header search table 1881 1.1 joerg RecordData::value_type Record[] = {HEADER_SEARCH_TABLE, BucketOffset, 1882 1.1 joerg NumHeaderSearchEntries, TableData.size()}; 1883 1.1 joerg TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end()); 1884 1.1 joerg Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData); 1885 1.1 joerg 1886 1.1 joerg // Free all of the strings we had to duplicate. 1887 1.1 joerg for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I) 1888 1.1 joerg free(const_cast<char *>(SavedStrings[I])); 1889 1.1 joerg } 1890 1.1 joerg 1891 1.1 joerg static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob, 1892 1.1 joerg unsigned SLocBufferBlobCompressedAbbrv, 1893 1.1 joerg unsigned SLocBufferBlobAbbrv) { 1894 1.1 joerg using RecordDataType = ASTWriter::RecordData::value_type; 1895 1.1 joerg 1896 1.1 joerg // Compress the buffer if possible. We expect that almost all PCM 1897 1.1 joerg // consumers will not want its contents. 1898 1.1 joerg SmallString<0> CompressedBuffer; 1899 1.1 joerg if (llvm::zlib::isAvailable()) { 1900 1.1 joerg llvm::Error E = llvm::zlib::compress(Blob.drop_back(1), CompressedBuffer); 1901 1.1 joerg if (!E) { 1902 1.1 joerg RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, 1903 1.1 joerg Blob.size() - 1}; 1904 1.1 joerg Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record, 1905 1.1 joerg CompressedBuffer); 1906 1.1 joerg return; 1907 1.1 joerg } 1908 1.1 joerg llvm::consumeError(std::move(E)); 1909 1.1 joerg } 1910 1.1 joerg 1911 1.1 joerg RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB}; 1912 1.1 joerg Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, Blob); 1913 1.1 joerg } 1914 1.1 joerg 1915 1.1 joerg /// Writes the block containing the serialized form of the 1916 1.1 joerg /// source manager. 1917 1.1 joerg /// 1918 1.1 joerg /// TODO: We should probably use an on-disk hash table (stored in a 1919 1.1 joerg /// blob), indexed based on the file name, so that we only create 1920 1.1 joerg /// entries for files that we actually need. In the common case (no 1921 1.1 joerg /// errors), we probably won't have to create file entries for any of 1922 1.1 joerg /// the files in the AST. 1923 1.1 joerg void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, 1924 1.1 joerg const Preprocessor &PP) { 1925 1.1 joerg RecordData Record; 1926 1.1 joerg 1927 1.1 joerg // Enter the source manager block. 1928 1.1 joerg Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 4); 1929 1.1.1.2 joerg const uint64_t SourceManagerBlockOffset = Stream.GetCurrentBitNo(); 1930 1.1 joerg 1931 1.1 joerg // Abbreviations for the various kinds of source-location entries. 1932 1.1 joerg unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream); 1933 1.1 joerg unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream); 1934 1.1 joerg unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream, false); 1935 1.1 joerg unsigned SLocBufferBlobCompressedAbbrv = 1936 1.1 joerg CreateSLocBufferBlobAbbrev(Stream, true); 1937 1.1 joerg unsigned SLocExpansionAbbrv = CreateSLocExpansionAbbrev(Stream); 1938 1.1 joerg 1939 1.1 joerg // Write out the source location entry table. We skip the first 1940 1.1 joerg // entry, which is always the same dummy entry. 1941 1.1 joerg std::vector<uint32_t> SLocEntryOffsets; 1942 1.1.1.2 joerg uint64_t SLocEntryOffsetsBase = Stream.GetCurrentBitNo(); 1943 1.1 joerg RecordData PreloadSLocs; 1944 1.1 joerg SLocEntryOffsets.reserve(SourceMgr.local_sloc_entry_size() - 1); 1945 1.1 joerg for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); 1946 1.1 joerg I != N; ++I) { 1947 1.1 joerg // Get this source location entry. 1948 1.1 joerg const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I); 1949 1.1 joerg FileID FID = FileID::get(I); 1950 1.1 joerg assert(&SourceMgr.getSLocEntry(FID) == SLoc); 1951 1.1 joerg 1952 1.1 joerg // Record the offset of this source-location entry. 1953 1.1.1.2 joerg uint64_t Offset = Stream.GetCurrentBitNo() - SLocEntryOffsetsBase; 1954 1.1.1.2 joerg assert((Offset >> 32) == 0 && "SLocEntry offset too large"); 1955 1.1.1.2 joerg SLocEntryOffsets.push_back(Offset); 1956 1.1 joerg 1957 1.1 joerg // Figure out which record code to use. 1958 1.1 joerg unsigned Code; 1959 1.1 joerg if (SLoc->isFile()) { 1960 1.1.1.2 joerg const SrcMgr::ContentCache *Cache = &SLoc->getFile().getContentCache(); 1961 1.1 joerg if (Cache->OrigEntry) { 1962 1.1 joerg Code = SM_SLOC_FILE_ENTRY; 1963 1.1 joerg } else 1964 1.1 joerg Code = SM_SLOC_BUFFER_ENTRY; 1965 1.1 joerg } else 1966 1.1 joerg Code = SM_SLOC_EXPANSION_ENTRY; 1967 1.1 joerg Record.clear(); 1968 1.1 joerg Record.push_back(Code); 1969 1.1 joerg 1970 1.1 joerg // Starting offset of this entry within this module, so skip the dummy. 1971 1.1 joerg Record.push_back(SLoc->getOffset() - 2); 1972 1.1 joerg if (SLoc->isFile()) { 1973 1.1 joerg const SrcMgr::FileInfo &File = SLoc->getFile(); 1974 1.1 joerg AddSourceLocation(File.getIncludeLoc(), Record); 1975 1.1 joerg Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding 1976 1.1 joerg Record.push_back(File.hasLineDirectives()); 1977 1.1 joerg 1978 1.1.1.2 joerg const SrcMgr::ContentCache *Content = &File.getContentCache(); 1979 1.1 joerg bool EmitBlob = false; 1980 1.1 joerg if (Content->OrigEntry) { 1981 1.1 joerg assert(Content->OrigEntry == Content->ContentsEntry && 1982 1.1 joerg "Writing to AST an overridden file is not supported"); 1983 1.1 joerg 1984 1.1 joerg // The source location entry is a file. Emit input file ID. 1985 1.1 joerg assert(InputFileIDs[Content->OrigEntry] != 0 && "Missed file entry"); 1986 1.1 joerg Record.push_back(InputFileIDs[Content->OrigEntry]); 1987 1.1 joerg 1988 1.1 joerg Record.push_back(File.NumCreatedFIDs); 1989 1.1 joerg 1990 1.1 joerg FileDeclIDsTy::iterator FDI = FileDeclIDs.find(FID); 1991 1.1 joerg if (FDI != FileDeclIDs.end()) { 1992 1.1 joerg Record.push_back(FDI->second->FirstDeclIndex); 1993 1.1 joerg Record.push_back(FDI->second->DeclIDs.size()); 1994 1.1 joerg } else { 1995 1.1 joerg Record.push_back(0); 1996 1.1 joerg Record.push_back(0); 1997 1.1 joerg } 1998 1.1 joerg 1999 1.1 joerg Stream.EmitRecordWithAbbrev(SLocFileAbbrv, Record); 2000 1.1 joerg 2001 1.1 joerg if (Content->BufferOverridden || Content->IsTransient) 2002 1.1 joerg EmitBlob = true; 2003 1.1 joerg } else { 2004 1.1 joerg // The source location entry is a buffer. The blob associated 2005 1.1 joerg // with this entry contains the contents of the buffer. 2006 1.1 joerg 2007 1.1 joerg // We add one to the size so that we capture the trailing NULL 2008 1.1 joerg // that is required by llvm::MemoryBuffer::getMemBuffer (on 2009 1.1 joerg // the reader side). 2010 1.1.1.2 joerg llvm::Optional<llvm::MemoryBufferRef> Buffer = 2011 1.1.1.2 joerg Content->getBufferOrNone(PP.getDiagnostics(), PP.getFileManager()); 2012 1.1.1.2 joerg StringRef Name = Buffer ? Buffer->getBufferIdentifier() : ""; 2013 1.1 joerg Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record, 2014 1.1 joerg StringRef(Name.data(), Name.size() + 1)); 2015 1.1 joerg EmitBlob = true; 2016 1.1 joerg 2017 1.1 joerg if (Name == "<built-in>") 2018 1.1 joerg PreloadSLocs.push_back(SLocEntryOffsets.size()); 2019 1.1 joerg } 2020 1.1 joerg 2021 1.1 joerg if (EmitBlob) { 2022 1.1 joerg // Include the implicit terminating null character in the on-disk buffer 2023 1.1 joerg // if we're writing it uncompressed. 2024 1.1.1.2 joerg llvm::Optional<llvm::MemoryBufferRef> Buffer = 2025 1.1.1.2 joerg Content->getBufferOrNone(PP.getDiagnostics(), PP.getFileManager()); 2026 1.1.1.2 joerg if (!Buffer) 2027 1.1.1.2 joerg Buffer = llvm::MemoryBufferRef("<<<INVALID BUFFER>>>", ""); 2028 1.1 joerg StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1); 2029 1.1 joerg emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv, 2030 1.1 joerg SLocBufferBlobAbbrv); 2031 1.1 joerg } 2032 1.1 joerg } else { 2033 1.1 joerg // The source location entry is a macro expansion. 2034 1.1 joerg const SrcMgr::ExpansionInfo &Expansion = SLoc->getExpansion(); 2035 1.1 joerg AddSourceLocation(Expansion.getSpellingLoc(), Record); 2036 1.1 joerg AddSourceLocation(Expansion.getExpansionLocStart(), Record); 2037 1.1 joerg AddSourceLocation(Expansion.isMacroArgExpansion() 2038 1.1 joerg ? SourceLocation() 2039 1.1 joerg : Expansion.getExpansionLocEnd(), 2040 1.1 joerg Record); 2041 1.1 joerg Record.push_back(Expansion.isExpansionTokenRange()); 2042 1.1 joerg 2043 1.1 joerg // Compute the token length for this macro expansion. 2044 1.1 joerg unsigned NextOffset = SourceMgr.getNextLocalOffset(); 2045 1.1 joerg if (I + 1 != N) 2046 1.1 joerg NextOffset = SourceMgr.getLocalSLocEntry(I + 1).getOffset(); 2047 1.1 joerg Record.push_back(NextOffset - SLoc->getOffset() - 1); 2048 1.1 joerg Stream.EmitRecordWithAbbrev(SLocExpansionAbbrv, Record); 2049 1.1 joerg } 2050 1.1 joerg } 2051 1.1 joerg 2052 1.1 joerg Stream.ExitBlock(); 2053 1.1 joerg 2054 1.1 joerg if (SLocEntryOffsets.empty()) 2055 1.1 joerg return; 2056 1.1 joerg 2057 1.1 joerg // Write the source-location offsets table into the AST block. This 2058 1.1 joerg // table is used for lazily loading source-location information. 2059 1.1 joerg using namespace llvm; 2060 1.1 joerg 2061 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2062 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS)); 2063 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs 2064 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // total size 2065 1.1.1.2 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // base offset 2066 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets 2067 1.1 joerg unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2068 1.1 joerg { 2069 1.1 joerg RecordData::value_type Record[] = { 2070 1.1 joerg SOURCE_LOCATION_OFFSETS, SLocEntryOffsets.size(), 2071 1.1.1.2 joerg SourceMgr.getNextLocalOffset() - 1 /* skip dummy */, 2072 1.1.1.2 joerg SLocEntryOffsetsBase - SourceManagerBlockOffset}; 2073 1.1 joerg Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, 2074 1.1 joerg bytes(SLocEntryOffsets)); 2075 1.1 joerg } 2076 1.1 joerg // Write the source location entry preloads array, telling the AST 2077 1.1 joerg // reader which source locations entries it should load eagerly. 2078 1.1 joerg Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs); 2079 1.1 joerg 2080 1.1 joerg // Write the line table. It depends on remapping working, so it must come 2081 1.1 joerg // after the source location offsets. 2082 1.1 joerg if (SourceMgr.hasLineTable()) { 2083 1.1 joerg LineTableInfo &LineTable = SourceMgr.getLineTable(); 2084 1.1 joerg 2085 1.1 joerg Record.clear(); 2086 1.1 joerg 2087 1.1 joerg // Emit the needed file names. 2088 1.1 joerg llvm::DenseMap<int, int> FilenameMap; 2089 1.1 joerg FilenameMap[-1] = -1; // For unspecified filenames. 2090 1.1 joerg for (const auto &L : LineTable) { 2091 1.1 joerg if (L.first.ID < 0) 2092 1.1 joerg continue; 2093 1.1 joerg for (auto &LE : L.second) { 2094 1.1 joerg if (FilenameMap.insert(std::make_pair(LE.FilenameID, 2095 1.1 joerg FilenameMap.size() - 1)).second) 2096 1.1 joerg AddPath(LineTable.getFilename(LE.FilenameID), Record); 2097 1.1 joerg } 2098 1.1 joerg } 2099 1.1 joerg Record.push_back(0); 2100 1.1 joerg 2101 1.1 joerg // Emit the line entries 2102 1.1 joerg for (const auto &L : LineTable) { 2103 1.1 joerg // Only emit entries for local files. 2104 1.1 joerg if (L.first.ID < 0) 2105 1.1 joerg continue; 2106 1.1 joerg 2107 1.1 joerg // Emit the file ID 2108 1.1 joerg Record.push_back(L.first.ID); 2109 1.1 joerg 2110 1.1 joerg // Emit the line entries 2111 1.1 joerg Record.push_back(L.second.size()); 2112 1.1 joerg for (const auto &LE : L.second) { 2113 1.1 joerg Record.push_back(LE.FileOffset); 2114 1.1 joerg Record.push_back(LE.LineNo); 2115 1.1 joerg Record.push_back(FilenameMap[LE.FilenameID]); 2116 1.1 joerg Record.push_back((unsigned)LE.FileKind); 2117 1.1 joerg Record.push_back(LE.IncludeOffset); 2118 1.1 joerg } 2119 1.1 joerg } 2120 1.1 joerg 2121 1.1 joerg Stream.EmitRecord(SOURCE_MANAGER_LINE_TABLE, Record); 2122 1.1 joerg } 2123 1.1 joerg } 2124 1.1 joerg 2125 1.1 joerg //===----------------------------------------------------------------------===// 2126 1.1 joerg // Preprocessor Serialization 2127 1.1 joerg //===----------------------------------------------------------------------===// 2128 1.1 joerg 2129 1.1 joerg static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule, 2130 1.1 joerg const Preprocessor &PP) { 2131 1.1 joerg if (MacroInfo *MI = MD->getMacroInfo()) 2132 1.1 joerg if (MI->isBuiltinMacro()) 2133 1.1 joerg return true; 2134 1.1 joerg 2135 1.1 joerg if (IsModule) { 2136 1.1 joerg SourceLocation Loc = MD->getLocation(); 2137 1.1 joerg if (Loc.isInvalid()) 2138 1.1 joerg return true; 2139 1.1 joerg if (PP.getSourceManager().getFileID(Loc) == PP.getPredefinesFileID()) 2140 1.1 joerg return true; 2141 1.1 joerg } 2142 1.1 joerg 2143 1.1 joerg return false; 2144 1.1 joerg } 2145 1.1 joerg 2146 1.1 joerg /// Writes the block containing the serialized form of the 2147 1.1 joerg /// preprocessor. 2148 1.1 joerg void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { 2149 1.1.1.2 joerg uint64_t MacroOffsetsBase = Stream.GetCurrentBitNo(); 2150 1.1.1.2 joerg 2151 1.1 joerg PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); 2152 1.1 joerg if (PPRec) 2153 1.1.1.2 joerg WritePreprocessorDetail(*PPRec, MacroOffsetsBase); 2154 1.1 joerg 2155 1.1 joerg RecordData Record; 2156 1.1 joerg RecordData ModuleMacroRecord; 2157 1.1 joerg 2158 1.1 joerg // If the preprocessor __COUNTER__ value has been bumped, remember it. 2159 1.1 joerg if (PP.getCounterValue() != 0) { 2160 1.1 joerg RecordData::value_type Record[] = {PP.getCounterValue()}; 2161 1.1 joerg Stream.EmitRecord(PP_COUNTER_VALUE, Record); 2162 1.1 joerg } 2163 1.1 joerg 2164 1.1 joerg if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) { 2165 1.1 joerg assert(!IsModule); 2166 1.1 joerg auto SkipInfo = PP.getPreambleSkipInfo(); 2167 1.1 joerg if (SkipInfo.hasValue()) { 2168 1.1 joerg Record.push_back(true); 2169 1.1 joerg AddSourceLocation(SkipInfo->HashTokenLoc, Record); 2170 1.1 joerg AddSourceLocation(SkipInfo->IfTokenLoc, Record); 2171 1.1 joerg Record.push_back(SkipInfo->FoundNonSkipPortion); 2172 1.1 joerg Record.push_back(SkipInfo->FoundElse); 2173 1.1 joerg AddSourceLocation(SkipInfo->ElseLoc, Record); 2174 1.1 joerg } else { 2175 1.1 joerg Record.push_back(false); 2176 1.1 joerg } 2177 1.1 joerg for (const auto &Cond : PP.getPreambleConditionalStack()) { 2178 1.1 joerg AddSourceLocation(Cond.IfLoc, Record); 2179 1.1 joerg Record.push_back(Cond.WasSkipping); 2180 1.1 joerg Record.push_back(Cond.FoundNonSkip); 2181 1.1 joerg Record.push_back(Cond.FoundElse); 2182 1.1 joerg } 2183 1.1 joerg Stream.EmitRecord(PP_CONDITIONAL_STACK, Record); 2184 1.1 joerg Record.clear(); 2185 1.1 joerg } 2186 1.1 joerg 2187 1.1 joerg // Enter the preprocessor block. 2188 1.1 joerg Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3); 2189 1.1 joerg 2190 1.1 joerg // If the AST file contains __DATE__ or __TIME__ emit a warning about this. 2191 1.1 joerg // FIXME: Include a location for the use, and say which one was used. 2192 1.1 joerg if (PP.SawDateOrTime()) 2193 1.1 joerg PP.Diag(SourceLocation(), diag::warn_module_uses_date_time) << IsModule; 2194 1.1 joerg 2195 1.1 joerg // Loop over all the macro directives that are live at the end of the file, 2196 1.1 joerg // emitting each to the PP section. 2197 1.1 joerg 2198 1.1 joerg // Construct the list of identifiers with macro directives that need to be 2199 1.1 joerg // serialized. 2200 1.1 joerg SmallVector<const IdentifierInfo *, 128> MacroIdentifiers; 2201 1.1 joerg for (auto &Id : PP.getIdentifierTable()) 2202 1.1 joerg if (Id.second->hadMacroDefinition() && 2203 1.1 joerg (!Id.second->isFromAST() || 2204 1.1 joerg Id.second->hasChangedSinceDeserialization())) 2205 1.1 joerg MacroIdentifiers.push_back(Id.second); 2206 1.1 joerg // Sort the set of macro definitions that need to be serialized by the 2207 1.1 joerg // name of the macro, to provide a stable ordering. 2208 1.1 joerg llvm::sort(MacroIdentifiers, llvm::deref<std::less<>>()); 2209 1.1 joerg 2210 1.1 joerg // Emit the macro directives as a list and associate the offset with the 2211 1.1 joerg // identifier they belong to. 2212 1.1 joerg for (const IdentifierInfo *Name : MacroIdentifiers) { 2213 1.1 joerg MacroDirective *MD = PP.getLocalMacroDirectiveHistory(Name); 2214 1.1.1.2 joerg uint64_t StartOffset = Stream.GetCurrentBitNo() - MacroOffsetsBase; 2215 1.1.1.2 joerg assert((StartOffset >> 32) == 0 && "Macro identifiers offset too large"); 2216 1.1 joerg 2217 1.1 joerg // Emit the macro directives in reverse source order. 2218 1.1 joerg for (; MD; MD = MD->getPrevious()) { 2219 1.1 joerg // Once we hit an ignored macro, we're done: the rest of the chain 2220 1.1 joerg // will all be ignored macros. 2221 1.1 joerg if (shouldIgnoreMacro(MD, IsModule, PP)) 2222 1.1 joerg break; 2223 1.1 joerg 2224 1.1 joerg AddSourceLocation(MD->getLocation(), Record); 2225 1.1 joerg Record.push_back(MD->getKind()); 2226 1.1 joerg if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) { 2227 1.1 joerg Record.push_back(getMacroRef(DefMD->getInfo(), Name)); 2228 1.1 joerg } else if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) { 2229 1.1 joerg Record.push_back(VisMD->isPublic()); 2230 1.1 joerg } 2231 1.1 joerg } 2232 1.1 joerg 2233 1.1 joerg // Write out any exported module macros. 2234 1.1 joerg bool EmittedModuleMacros = false; 2235 1.1 joerg // We write out exported module macros for PCH as well. 2236 1.1 joerg auto Leafs = PP.getLeafModuleMacros(Name); 2237 1.1 joerg SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end()); 2238 1.1 joerg llvm::DenseMap<ModuleMacro*, unsigned> Visits; 2239 1.1 joerg while (!Worklist.empty()) { 2240 1.1 joerg auto *Macro = Worklist.pop_back_val(); 2241 1.1 joerg 2242 1.1 joerg // Emit a record indicating this submodule exports this macro. 2243 1.1 joerg ModuleMacroRecord.push_back( 2244 1.1 joerg getSubmoduleID(Macro->getOwningModule())); 2245 1.1 joerg ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name)); 2246 1.1 joerg for (auto *M : Macro->overrides()) 2247 1.1 joerg ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule())); 2248 1.1 joerg 2249 1.1 joerg Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord); 2250 1.1 joerg ModuleMacroRecord.clear(); 2251 1.1 joerg 2252 1.1 joerg // Enqueue overridden macros once we've visited all their ancestors. 2253 1.1 joerg for (auto *M : Macro->overrides()) 2254 1.1 joerg if (++Visits[M] == M->getNumOverridingMacros()) 2255 1.1 joerg Worklist.push_back(M); 2256 1.1 joerg 2257 1.1 joerg EmittedModuleMacros = true; 2258 1.1 joerg } 2259 1.1 joerg 2260 1.1 joerg if (Record.empty() && !EmittedModuleMacros) 2261 1.1 joerg continue; 2262 1.1 joerg 2263 1.1 joerg IdentMacroDirectivesOffsetMap[Name] = StartOffset; 2264 1.1 joerg Stream.EmitRecord(PP_MACRO_DIRECTIVE_HISTORY, Record); 2265 1.1 joerg Record.clear(); 2266 1.1 joerg } 2267 1.1 joerg 2268 1.1 joerg /// Offsets of each of the macros into the bitstream, indexed by 2269 1.1 joerg /// the local macro ID 2270 1.1 joerg /// 2271 1.1 joerg /// For each identifier that is associated with a macro, this map 2272 1.1 joerg /// provides the offset into the bitstream where that macro is 2273 1.1 joerg /// defined. 2274 1.1 joerg std::vector<uint32_t> MacroOffsets; 2275 1.1 joerg 2276 1.1 joerg for (unsigned I = 0, N = MacroInfosToEmit.size(); I != N; ++I) { 2277 1.1 joerg const IdentifierInfo *Name = MacroInfosToEmit[I].Name; 2278 1.1 joerg MacroInfo *MI = MacroInfosToEmit[I].MI; 2279 1.1 joerg MacroID ID = MacroInfosToEmit[I].ID; 2280 1.1 joerg 2281 1.1 joerg if (ID < FirstMacroID) { 2282 1.1 joerg assert(0 && "Loaded MacroInfo entered MacroInfosToEmit ?"); 2283 1.1 joerg continue; 2284 1.1 joerg } 2285 1.1 joerg 2286 1.1 joerg // Record the local offset of this macro. 2287 1.1 joerg unsigned Index = ID - FirstMacroID; 2288 1.1.1.2 joerg if (Index >= MacroOffsets.size()) 2289 1.1.1.2 joerg MacroOffsets.resize(Index + 1); 2290 1.1 joerg 2291 1.1.1.2 joerg uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase; 2292 1.1.1.2 joerg assert((Offset >> 32) == 0 && "Macro offset too large"); 2293 1.1.1.2 joerg MacroOffsets[Index] = Offset; 2294 1.1 joerg 2295 1.1 joerg AddIdentifierRef(Name, Record); 2296 1.1 joerg AddSourceLocation(MI->getDefinitionLoc(), Record); 2297 1.1 joerg AddSourceLocation(MI->getDefinitionEndLoc(), Record); 2298 1.1 joerg Record.push_back(MI->isUsed()); 2299 1.1 joerg Record.push_back(MI->isUsedForHeaderGuard()); 2300 1.1 joerg unsigned Code; 2301 1.1 joerg if (MI->isObjectLike()) { 2302 1.1 joerg Code = PP_MACRO_OBJECT_LIKE; 2303 1.1 joerg } else { 2304 1.1 joerg Code = PP_MACRO_FUNCTION_LIKE; 2305 1.1 joerg 2306 1.1 joerg Record.push_back(MI->isC99Varargs()); 2307 1.1 joerg Record.push_back(MI->isGNUVarargs()); 2308 1.1 joerg Record.push_back(MI->hasCommaPasting()); 2309 1.1 joerg Record.push_back(MI->getNumParams()); 2310 1.1 joerg for (const IdentifierInfo *Param : MI->params()) 2311 1.1 joerg AddIdentifierRef(Param, Record); 2312 1.1 joerg } 2313 1.1 joerg 2314 1.1 joerg // If we have a detailed preprocessing record, record the macro definition 2315 1.1 joerg // ID that corresponds to this macro. 2316 1.1 joerg if (PPRec) 2317 1.1 joerg Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]); 2318 1.1 joerg 2319 1.1 joerg Stream.EmitRecord(Code, Record); 2320 1.1 joerg Record.clear(); 2321 1.1 joerg 2322 1.1 joerg // Emit the tokens array. 2323 1.1 joerg for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) { 2324 1.1 joerg // Note that we know that the preprocessor does not have any annotation 2325 1.1 joerg // tokens in it because they are created by the parser, and thus can't 2326 1.1 joerg // be in a macro definition. 2327 1.1 joerg const Token &Tok = MI->getReplacementToken(TokNo); 2328 1.1 joerg AddToken(Tok, Record); 2329 1.1 joerg Stream.EmitRecord(PP_TOKEN, Record); 2330 1.1 joerg Record.clear(); 2331 1.1 joerg } 2332 1.1 joerg ++NumMacros; 2333 1.1 joerg } 2334 1.1 joerg 2335 1.1 joerg Stream.ExitBlock(); 2336 1.1 joerg 2337 1.1 joerg // Write the offsets table for macro IDs. 2338 1.1 joerg using namespace llvm; 2339 1.1 joerg 2340 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2341 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(MACRO_OFFSET)); 2342 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros 2343 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID 2344 1.1.1.2 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // base offset 2345 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2346 1.1 joerg 2347 1.1 joerg unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2348 1.1 joerg { 2349 1.1 joerg RecordData::value_type Record[] = {MACRO_OFFSET, MacroOffsets.size(), 2350 1.1.1.2 joerg FirstMacroID - NUM_PREDEF_MACRO_IDS, 2351 1.1.1.2 joerg MacroOffsetsBase - ASTBlockStartOffset}; 2352 1.1 joerg Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, bytes(MacroOffsets)); 2353 1.1 joerg } 2354 1.1 joerg } 2355 1.1 joerg 2356 1.1.1.2 joerg void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec, 2357 1.1.1.2 joerg uint64_t MacroOffsetsBase) { 2358 1.1 joerg if (PPRec.local_begin() == PPRec.local_end()) 2359 1.1 joerg return; 2360 1.1 joerg 2361 1.1 joerg SmallVector<PPEntityOffset, 64> PreprocessedEntityOffsets; 2362 1.1 joerg 2363 1.1 joerg // Enter the preprocessor block. 2364 1.1 joerg Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3); 2365 1.1 joerg 2366 1.1 joerg // If the preprocessor has a preprocessing record, emit it. 2367 1.1 joerg unsigned NumPreprocessingRecords = 0; 2368 1.1 joerg using namespace llvm; 2369 1.1 joerg 2370 1.1 joerg // Set up the abbreviation for 2371 1.1 joerg unsigned InclusionAbbrev = 0; 2372 1.1 joerg { 2373 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2374 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE)); 2375 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length 2376 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes 2377 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind 2378 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // imported module 2379 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2380 1.1 joerg InclusionAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2381 1.1 joerg } 2382 1.1 joerg 2383 1.1 joerg unsigned FirstPreprocessorEntityID 2384 1.1 joerg = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0) 2385 1.1 joerg + NUM_PREDEF_PP_ENTITY_IDS; 2386 1.1 joerg unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID; 2387 1.1 joerg RecordData Record; 2388 1.1 joerg for (PreprocessingRecord::iterator E = PPRec.local_begin(), 2389 1.1 joerg EEnd = PPRec.local_end(); 2390 1.1 joerg E != EEnd; 2391 1.1 joerg (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) { 2392 1.1 joerg Record.clear(); 2393 1.1 joerg 2394 1.1.1.2 joerg uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase; 2395 1.1.1.2 joerg assert((Offset >> 32) == 0 && "Preprocessed entity offset too large"); 2396 1.1 joerg PreprocessedEntityOffsets.push_back( 2397 1.1.1.2 joerg PPEntityOffset((*E)->getSourceRange(), Offset)); 2398 1.1 joerg 2399 1.1 joerg if (auto *MD = dyn_cast<MacroDefinitionRecord>(*E)) { 2400 1.1 joerg // Record this macro definition's ID. 2401 1.1 joerg MacroDefinitions[MD] = NextPreprocessorEntityID; 2402 1.1 joerg 2403 1.1 joerg AddIdentifierRef(MD->getName(), Record); 2404 1.1 joerg Stream.EmitRecord(PPD_MACRO_DEFINITION, Record); 2405 1.1 joerg continue; 2406 1.1 joerg } 2407 1.1 joerg 2408 1.1 joerg if (auto *ME = dyn_cast<MacroExpansion>(*E)) { 2409 1.1 joerg Record.push_back(ME->isBuiltinMacro()); 2410 1.1 joerg if (ME->isBuiltinMacro()) 2411 1.1 joerg AddIdentifierRef(ME->getName(), Record); 2412 1.1 joerg else 2413 1.1 joerg Record.push_back(MacroDefinitions[ME->getDefinition()]); 2414 1.1 joerg Stream.EmitRecord(PPD_MACRO_EXPANSION, Record); 2415 1.1 joerg continue; 2416 1.1 joerg } 2417 1.1 joerg 2418 1.1 joerg if (auto *ID = dyn_cast<InclusionDirective>(*E)) { 2419 1.1 joerg Record.push_back(PPD_INCLUSION_DIRECTIVE); 2420 1.1 joerg Record.push_back(ID->getFileName().size()); 2421 1.1 joerg Record.push_back(ID->wasInQuotes()); 2422 1.1 joerg Record.push_back(static_cast<unsigned>(ID->getKind())); 2423 1.1 joerg Record.push_back(ID->importedModule()); 2424 1.1 joerg SmallString<64> Buffer; 2425 1.1 joerg Buffer += ID->getFileName(); 2426 1.1 joerg // Check that the FileEntry is not null because it was not resolved and 2427 1.1 joerg // we create a PCH even with compiler errors. 2428 1.1 joerg if (ID->getFile()) 2429 1.1 joerg Buffer += ID->getFile()->getName(); 2430 1.1 joerg Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); 2431 1.1 joerg continue; 2432 1.1 joerg } 2433 1.1 joerg 2434 1.1 joerg llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter"); 2435 1.1 joerg } 2436 1.1 joerg Stream.ExitBlock(); 2437 1.1 joerg 2438 1.1 joerg // Write the offsets table for the preprocessing record. 2439 1.1 joerg if (NumPreprocessingRecords > 0) { 2440 1.1 joerg assert(PreprocessedEntityOffsets.size() == NumPreprocessingRecords); 2441 1.1 joerg 2442 1.1 joerg // Write the offsets table for identifier IDs. 2443 1.1 joerg using namespace llvm; 2444 1.1 joerg 2445 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2446 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(PPD_ENTITIES_OFFSETS)); 2447 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first pp entity 2448 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2449 1.1 joerg unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2450 1.1 joerg 2451 1.1 joerg RecordData::value_type Record[] = {PPD_ENTITIES_OFFSETS, 2452 1.1 joerg FirstPreprocessorEntityID - 2453 1.1 joerg NUM_PREDEF_PP_ENTITY_IDS}; 2454 1.1 joerg Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record, 2455 1.1 joerg bytes(PreprocessedEntityOffsets)); 2456 1.1 joerg } 2457 1.1 joerg 2458 1.1 joerg // Write the skipped region table for the preprocessing record. 2459 1.1 joerg ArrayRef<SourceRange> SkippedRanges = PPRec.getSkippedRanges(); 2460 1.1 joerg if (SkippedRanges.size() > 0) { 2461 1.1 joerg std::vector<PPSkippedRange> SerializedSkippedRanges; 2462 1.1 joerg SerializedSkippedRanges.reserve(SkippedRanges.size()); 2463 1.1 joerg for (auto const& Range : SkippedRanges) 2464 1.1 joerg SerializedSkippedRanges.emplace_back(Range); 2465 1.1 joerg 2466 1.1 joerg using namespace llvm; 2467 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2468 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(PPD_SKIPPED_RANGES)); 2469 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2470 1.1 joerg unsigned PPESkippedRangeAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2471 1.1 joerg 2472 1.1 joerg Record.clear(); 2473 1.1 joerg Record.push_back(PPD_SKIPPED_RANGES); 2474 1.1 joerg Stream.EmitRecordWithBlob(PPESkippedRangeAbbrev, Record, 2475 1.1 joerg bytes(SerializedSkippedRanges)); 2476 1.1 joerg } 2477 1.1 joerg } 2478 1.1 joerg 2479 1.1 joerg unsigned ASTWriter::getLocalOrImportedSubmoduleID(Module *Mod) { 2480 1.1 joerg if (!Mod) 2481 1.1 joerg return 0; 2482 1.1 joerg 2483 1.1 joerg llvm::DenseMap<Module *, unsigned>::iterator Known = SubmoduleIDs.find(Mod); 2484 1.1 joerg if (Known != SubmoduleIDs.end()) 2485 1.1 joerg return Known->second; 2486 1.1 joerg 2487 1.1 joerg auto *Top = Mod->getTopLevelModule(); 2488 1.1 joerg if (Top != WritingModule && 2489 1.1 joerg (getLangOpts().CompilingPCH || 2490 1.1 joerg !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))) 2491 1.1 joerg return 0; 2492 1.1 joerg 2493 1.1 joerg return SubmoduleIDs[Mod] = NextSubmoduleID++; 2494 1.1 joerg } 2495 1.1 joerg 2496 1.1 joerg unsigned ASTWriter::getSubmoduleID(Module *Mod) { 2497 1.1 joerg // FIXME: This can easily happen, if we have a reference to a submodule that 2498 1.1 joerg // did not result in us loading a module file for that submodule. For 2499 1.1 joerg // instance, a cross-top-level-module 'conflict' declaration will hit this. 2500 1.1 joerg unsigned ID = getLocalOrImportedSubmoduleID(Mod); 2501 1.1 joerg assert((ID || !Mod) && 2502 1.1 joerg "asked for module ID for non-local, non-imported module"); 2503 1.1 joerg return ID; 2504 1.1 joerg } 2505 1.1 joerg 2506 1.1 joerg /// Compute the number of modules within the given tree (including the 2507 1.1 joerg /// given module). 2508 1.1 joerg static unsigned getNumberOfModules(Module *Mod) { 2509 1.1 joerg unsigned ChildModules = 0; 2510 1.1 joerg for (auto Sub = Mod->submodule_begin(), SubEnd = Mod->submodule_end(); 2511 1.1 joerg Sub != SubEnd; ++Sub) 2512 1.1 joerg ChildModules += getNumberOfModules(*Sub); 2513 1.1 joerg 2514 1.1 joerg return ChildModules + 1; 2515 1.1 joerg } 2516 1.1 joerg 2517 1.1 joerg void ASTWriter::WriteSubmodules(Module *WritingModule) { 2518 1.1 joerg // Enter the submodule description block. 2519 1.1 joerg Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5); 2520 1.1 joerg 2521 1.1 joerg // Write the abbreviations needed for the submodules block. 2522 1.1 joerg using namespace llvm; 2523 1.1 joerg 2524 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2525 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION)); 2526 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID 2527 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent 2528 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Kind 2529 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework 2530 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit 2531 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem 2532 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExternC 2533 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules... 2534 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit... 2535 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild... 2536 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ConfigMacrosExh... 2537 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModuleMapIsPriv... 2538 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2539 1.1 joerg unsigned DefinitionAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2540 1.1 joerg 2541 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2542 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_HEADER)); 2543 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2544 1.1 joerg unsigned UmbrellaAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2545 1.1 joerg 2546 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2547 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER)); 2548 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2549 1.1 joerg unsigned HeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2550 1.1 joerg 2551 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2552 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TOPHEADER)); 2553 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2554 1.1 joerg unsigned TopHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2555 1.1 joerg 2556 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2557 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_DIR)); 2558 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2559 1.1 joerg unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2560 1.1 joerg 2561 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2562 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_REQUIRES)); 2563 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // State 2564 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Feature 2565 1.1 joerg unsigned RequiresAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2566 1.1 joerg 2567 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2568 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXCLUDED_HEADER)); 2569 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2570 1.1 joerg unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2571 1.1 joerg 2572 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2573 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TEXTUAL_HEADER)); 2574 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2575 1.1 joerg unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2576 1.1 joerg 2577 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2578 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_HEADER)); 2579 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2580 1.1 joerg unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2581 1.1 joerg 2582 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2583 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER)); 2584 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2585 1.1 joerg unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2586 1.1 joerg 2587 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2588 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY)); 2589 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework 2590 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name 2591 1.1 joerg unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2592 1.1 joerg 2593 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2594 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_CONFIG_MACRO)); 2595 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name 2596 1.1 joerg unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2597 1.1 joerg 2598 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2599 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_CONFLICT)); 2600 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Other module 2601 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Message 2602 1.1 joerg unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2603 1.1 joerg 2604 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2605 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXPORT_AS)); 2606 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name 2607 1.1 joerg unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2608 1.1 joerg 2609 1.1 joerg // Write the submodule metadata block. 2610 1.1 joerg RecordData::value_type Record[] = { 2611 1.1 joerg getNumberOfModules(WritingModule), 2612 1.1 joerg FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS}; 2613 1.1 joerg Stream.EmitRecord(SUBMODULE_METADATA, Record); 2614 1.1 joerg 2615 1.1 joerg // Write all of the submodules. 2616 1.1 joerg std::queue<Module *> Q; 2617 1.1 joerg Q.push(WritingModule); 2618 1.1 joerg while (!Q.empty()) { 2619 1.1 joerg Module *Mod = Q.front(); 2620 1.1 joerg Q.pop(); 2621 1.1 joerg unsigned ID = getSubmoduleID(Mod); 2622 1.1 joerg 2623 1.1 joerg uint64_t ParentID = 0; 2624 1.1 joerg if (Mod->Parent) { 2625 1.1 joerg assert(SubmoduleIDs[Mod->Parent] && "Submodule parent not written?"); 2626 1.1 joerg ParentID = SubmoduleIDs[Mod->Parent]; 2627 1.1 joerg } 2628 1.1 joerg 2629 1.1 joerg // Emit the definition of the block. 2630 1.1 joerg { 2631 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_DEFINITION, 2632 1.1 joerg ID, 2633 1.1 joerg ParentID, 2634 1.1 joerg (RecordData::value_type)Mod->Kind, 2635 1.1 joerg Mod->IsFramework, 2636 1.1 joerg Mod->IsExplicit, 2637 1.1 joerg Mod->IsSystem, 2638 1.1 joerg Mod->IsExternC, 2639 1.1 joerg Mod->InferSubmodules, 2640 1.1 joerg Mod->InferExplicitSubmodules, 2641 1.1 joerg Mod->InferExportWildcard, 2642 1.1 joerg Mod->ConfigMacrosExhaustive, 2643 1.1 joerg Mod->ModuleMapIsPrivate}; 2644 1.1 joerg Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name); 2645 1.1 joerg } 2646 1.1 joerg 2647 1.1 joerg // Emit the requirements. 2648 1.1 joerg for (const auto &R : Mod->Requirements) { 2649 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_REQUIRES, R.second}; 2650 1.1 joerg Stream.EmitRecordWithBlob(RequiresAbbrev, Record, R.first); 2651 1.1 joerg } 2652 1.1 joerg 2653 1.1 joerg // Emit the umbrella header, if there is one. 2654 1.1 joerg if (auto UmbrellaHeader = Mod->getUmbrellaHeader()) { 2655 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_HEADER}; 2656 1.1 joerg Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, 2657 1.1 joerg UmbrellaHeader.NameAsWritten); 2658 1.1 joerg } else if (auto UmbrellaDir = Mod->getUmbrellaDir()) { 2659 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_DIR}; 2660 1.1 joerg Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record, 2661 1.1 joerg UmbrellaDir.NameAsWritten); 2662 1.1 joerg } 2663 1.1 joerg 2664 1.1 joerg // Emit the headers. 2665 1.1 joerg struct { 2666 1.1 joerg unsigned RecordKind; 2667 1.1 joerg unsigned Abbrev; 2668 1.1 joerg Module::HeaderKind HeaderKind; 2669 1.1 joerg } HeaderLists[] = { 2670 1.1 joerg {SUBMODULE_HEADER, HeaderAbbrev, Module::HK_Normal}, 2671 1.1 joerg {SUBMODULE_TEXTUAL_HEADER, TextualHeaderAbbrev, Module::HK_Textual}, 2672 1.1 joerg {SUBMODULE_PRIVATE_HEADER, PrivateHeaderAbbrev, Module::HK_Private}, 2673 1.1 joerg {SUBMODULE_PRIVATE_TEXTUAL_HEADER, PrivateTextualHeaderAbbrev, 2674 1.1 joerg Module::HK_PrivateTextual}, 2675 1.1 joerg {SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Module::HK_Excluded} 2676 1.1 joerg }; 2677 1.1 joerg for (auto &HL : HeaderLists) { 2678 1.1 joerg RecordData::value_type Record[] = {HL.RecordKind}; 2679 1.1 joerg for (auto &H : Mod->Headers[HL.HeaderKind]) 2680 1.1 joerg Stream.EmitRecordWithBlob(HL.Abbrev, Record, H.NameAsWritten); 2681 1.1 joerg } 2682 1.1 joerg 2683 1.1 joerg // Emit the top headers. 2684 1.1 joerg { 2685 1.1 joerg auto TopHeaders = Mod->getTopHeaders(PP->getFileManager()); 2686 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_TOPHEADER}; 2687 1.1 joerg for (auto *H : TopHeaders) 2688 1.1 joerg Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, H->getName()); 2689 1.1 joerg } 2690 1.1 joerg 2691 1.1 joerg // Emit the imports. 2692 1.1 joerg if (!Mod->Imports.empty()) { 2693 1.1 joerg RecordData Record; 2694 1.1 joerg for (auto *I : Mod->Imports) 2695 1.1 joerg Record.push_back(getSubmoduleID(I)); 2696 1.1 joerg Stream.EmitRecord(SUBMODULE_IMPORTS, Record); 2697 1.1 joerg } 2698 1.1 joerg 2699 1.1 joerg // Emit the exports. 2700 1.1 joerg if (!Mod->Exports.empty()) { 2701 1.1 joerg RecordData Record; 2702 1.1 joerg for (const auto &E : Mod->Exports) { 2703 1.1 joerg // FIXME: This may fail; we don't require that all exported modules 2704 1.1 joerg // are local or imported. 2705 1.1 joerg Record.push_back(getSubmoduleID(E.getPointer())); 2706 1.1 joerg Record.push_back(E.getInt()); 2707 1.1 joerg } 2708 1.1 joerg Stream.EmitRecord(SUBMODULE_EXPORTS, Record); 2709 1.1 joerg } 2710 1.1 joerg 2711 1.1 joerg //FIXME: How do we emit the 'use'd modules? They may not be submodules. 2712 1.1 joerg // Might be unnecessary as use declarations are only used to build the 2713 1.1 joerg // module itself. 2714 1.1 joerg 2715 1.1 joerg // Emit the link libraries. 2716 1.1 joerg for (const auto &LL : Mod->LinkLibraries) { 2717 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_LINK_LIBRARY, 2718 1.1 joerg LL.IsFramework}; 2719 1.1 joerg Stream.EmitRecordWithBlob(LinkLibraryAbbrev, Record, LL.Library); 2720 1.1 joerg } 2721 1.1 joerg 2722 1.1 joerg // Emit the conflicts. 2723 1.1 joerg for (const auto &C : Mod->Conflicts) { 2724 1.1 joerg // FIXME: This may fail; we don't require that all conflicting modules 2725 1.1 joerg // are local or imported. 2726 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_CONFLICT, 2727 1.1 joerg getSubmoduleID(C.Other)}; 2728 1.1 joerg Stream.EmitRecordWithBlob(ConflictAbbrev, Record, C.Message); 2729 1.1 joerg } 2730 1.1 joerg 2731 1.1 joerg // Emit the configuration macros. 2732 1.1 joerg for (const auto &CM : Mod->ConfigMacros) { 2733 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_CONFIG_MACRO}; 2734 1.1 joerg Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record, CM); 2735 1.1 joerg } 2736 1.1 joerg 2737 1.1 joerg // Emit the initializers, if any. 2738 1.1 joerg RecordData Inits; 2739 1.1 joerg for (Decl *D : Context->getModuleInitializers(Mod)) 2740 1.1 joerg Inits.push_back(GetDeclRef(D)); 2741 1.1 joerg if (!Inits.empty()) 2742 1.1 joerg Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits); 2743 1.1 joerg 2744 1.1 joerg // Emit the name of the re-exported module, if any. 2745 1.1 joerg if (!Mod->ExportAsModule.empty()) { 2746 1.1 joerg RecordData::value_type Record[] = {SUBMODULE_EXPORT_AS}; 2747 1.1 joerg Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->ExportAsModule); 2748 1.1 joerg } 2749 1.1 joerg 2750 1.1 joerg // Queue up the submodules of this module. 2751 1.1 joerg for (auto *M : Mod->submodules()) 2752 1.1 joerg Q.push(M); 2753 1.1 joerg } 2754 1.1 joerg 2755 1.1 joerg Stream.ExitBlock(); 2756 1.1 joerg 2757 1.1 joerg assert((NextSubmoduleID - FirstSubmoduleID == 2758 1.1 joerg getNumberOfModules(WritingModule)) && 2759 1.1 joerg "Wrong # of submodules; found a reference to a non-local, " 2760 1.1 joerg "non-imported submodule?"); 2761 1.1 joerg } 2762 1.1 joerg 2763 1.1 joerg void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, 2764 1.1 joerg bool isModule) { 2765 1.1 joerg llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64> 2766 1.1 joerg DiagStateIDMap; 2767 1.1 joerg unsigned CurrID = 0; 2768 1.1 joerg RecordData Record; 2769 1.1 joerg 2770 1.1 joerg auto EncodeDiagStateFlags = 2771 1.1 joerg [](const DiagnosticsEngine::DiagState *DS) -> unsigned { 2772 1.1 joerg unsigned Result = (unsigned)DS->ExtBehavior; 2773 1.1 joerg for (unsigned Val : 2774 1.1 joerg {(unsigned)DS->IgnoreAllWarnings, (unsigned)DS->EnableAllWarnings, 2775 1.1 joerg (unsigned)DS->WarningsAsErrors, (unsigned)DS->ErrorsAsFatal, 2776 1.1 joerg (unsigned)DS->SuppressSystemWarnings}) 2777 1.1 joerg Result = (Result << 1) | Val; 2778 1.1 joerg return Result; 2779 1.1 joerg }; 2780 1.1 joerg 2781 1.1 joerg unsigned Flags = EncodeDiagStateFlags(Diag.DiagStatesByLoc.FirstDiagState); 2782 1.1 joerg Record.push_back(Flags); 2783 1.1 joerg 2784 1.1 joerg auto AddDiagState = [&](const DiagnosticsEngine::DiagState *State, 2785 1.1 joerg bool IncludeNonPragmaStates) { 2786 1.1 joerg // Ensure that the diagnostic state wasn't modified since it was created. 2787 1.1 joerg // We will not correctly round-trip this information otherwise. 2788 1.1 joerg assert(Flags == EncodeDiagStateFlags(State) && 2789 1.1 joerg "diag state flags vary in single AST file"); 2790 1.1 joerg 2791 1.1 joerg unsigned &DiagStateID = DiagStateIDMap[State]; 2792 1.1 joerg Record.push_back(DiagStateID); 2793 1.1 joerg 2794 1.1 joerg if (DiagStateID == 0) { 2795 1.1 joerg DiagStateID = ++CurrID; 2796 1.1 joerg 2797 1.1 joerg // Add a placeholder for the number of mappings. 2798 1.1 joerg auto SizeIdx = Record.size(); 2799 1.1 joerg Record.emplace_back(); 2800 1.1 joerg for (const auto &I : *State) { 2801 1.1 joerg if (I.second.isPragma() || IncludeNonPragmaStates) { 2802 1.1 joerg Record.push_back(I.first); 2803 1.1 joerg Record.push_back(I.second.serialize()); 2804 1.1 joerg } 2805 1.1 joerg } 2806 1.1 joerg // Update the placeholder. 2807 1.1 joerg Record[SizeIdx] = (Record.size() - SizeIdx) / 2; 2808 1.1 joerg } 2809 1.1 joerg }; 2810 1.1 joerg 2811 1.1 joerg AddDiagState(Diag.DiagStatesByLoc.FirstDiagState, isModule); 2812 1.1 joerg 2813 1.1 joerg // Reserve a spot for the number of locations with state transitions. 2814 1.1 joerg auto NumLocationsIdx = Record.size(); 2815 1.1 joerg Record.emplace_back(); 2816 1.1 joerg 2817 1.1 joerg // Emit the state transitions. 2818 1.1 joerg unsigned NumLocations = 0; 2819 1.1 joerg for (auto &FileIDAndFile : Diag.DiagStatesByLoc.Files) { 2820 1.1 joerg if (!FileIDAndFile.first.isValid() || 2821 1.1 joerg !FileIDAndFile.second.HasLocalTransitions) 2822 1.1 joerg continue; 2823 1.1 joerg ++NumLocations; 2824 1.1 joerg 2825 1.1 joerg SourceLocation Loc = Diag.SourceMgr->getComposedLoc(FileIDAndFile.first, 0); 2826 1.1 joerg assert(!Loc.isInvalid() && "start loc for valid FileID is invalid"); 2827 1.1 joerg AddSourceLocation(Loc, Record); 2828 1.1 joerg 2829 1.1 joerg Record.push_back(FileIDAndFile.second.StateTransitions.size()); 2830 1.1 joerg for (auto &StatePoint : FileIDAndFile.second.StateTransitions) { 2831 1.1 joerg Record.push_back(StatePoint.Offset); 2832 1.1 joerg AddDiagState(StatePoint.State, false); 2833 1.1 joerg } 2834 1.1 joerg } 2835 1.1 joerg 2836 1.1 joerg // Backpatch the number of locations. 2837 1.1 joerg Record[NumLocationsIdx] = NumLocations; 2838 1.1 joerg 2839 1.1 joerg // Emit CurDiagStateLoc. Do it last in order to match source order. 2840 1.1 joerg // 2841 1.1 joerg // This also protects against a hypothetical corner case with simulating 2842 1.1 joerg // -Werror settings for implicit modules in the ASTReader, where reading 2843 1.1 joerg // CurDiagState out of context could change whether warning pragmas are 2844 1.1 joerg // treated as errors. 2845 1.1 joerg AddSourceLocation(Diag.DiagStatesByLoc.CurDiagStateLoc, Record); 2846 1.1 joerg AddDiagState(Diag.DiagStatesByLoc.CurDiagState, false); 2847 1.1 joerg 2848 1.1 joerg Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record); 2849 1.1 joerg } 2850 1.1 joerg 2851 1.1 joerg //===----------------------------------------------------------------------===// 2852 1.1 joerg // Type Serialization 2853 1.1 joerg //===----------------------------------------------------------------------===// 2854 1.1 joerg 2855 1.1 joerg /// Write the representation of a type to the AST stream. 2856 1.1 joerg void ASTWriter::WriteType(QualType T) { 2857 1.1 joerg TypeIdx &IdxRef = TypeIdxs[T]; 2858 1.1 joerg if (IdxRef.getIndex() == 0) // we haven't seen this type before. 2859 1.1 joerg IdxRef = TypeIdx(NextTypeID++); 2860 1.1 joerg TypeIdx Idx = IdxRef; 2861 1.1 joerg 2862 1.1 joerg assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); 2863 1.1 joerg 2864 1.1 joerg // Emit the type's representation. 2865 1.1.1.2 joerg uint64_t Offset = ASTTypeWriter(*this).write(T) - DeclTypesBlockStartOffset; 2866 1.1 joerg 2867 1.1 joerg // Record the offset for this type. 2868 1.1 joerg unsigned Index = Idx.getIndex() - FirstTypeID; 2869 1.1 joerg if (TypeOffsets.size() == Index) 2870 1.1.1.2 joerg TypeOffsets.emplace_back(Offset); 2871 1.1 joerg else if (TypeOffsets.size() < Index) { 2872 1.1 joerg TypeOffsets.resize(Index + 1); 2873 1.1.1.2 joerg TypeOffsets[Index].setBitOffset(Offset); 2874 1.1 joerg } else { 2875 1.1 joerg llvm_unreachable("Types emitted in wrong order"); 2876 1.1 joerg } 2877 1.1 joerg } 2878 1.1 joerg 2879 1.1 joerg //===----------------------------------------------------------------------===// 2880 1.1 joerg // Declaration Serialization 2881 1.1 joerg //===----------------------------------------------------------------------===// 2882 1.1 joerg 2883 1.1 joerg /// Write the block containing all of the declaration IDs 2884 1.1 joerg /// lexically declared within the given DeclContext. 2885 1.1 joerg /// 2886 1.1 joerg /// \returns the offset of the DECL_CONTEXT_LEXICAL block within the 2887 1.1 joerg /// bitstream, or 0 if no block was written. 2888 1.1 joerg uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, 2889 1.1 joerg DeclContext *DC) { 2890 1.1 joerg if (DC->decls_empty()) 2891 1.1 joerg return 0; 2892 1.1 joerg 2893 1.1 joerg uint64_t Offset = Stream.GetCurrentBitNo(); 2894 1.1 joerg SmallVector<uint32_t, 128> KindDeclPairs; 2895 1.1 joerg for (const auto *D : DC->decls()) { 2896 1.1 joerg KindDeclPairs.push_back(D->getKind()); 2897 1.1 joerg KindDeclPairs.push_back(GetDeclRef(D)); 2898 1.1 joerg } 2899 1.1 joerg 2900 1.1 joerg ++NumLexicalDeclContexts; 2901 1.1 joerg RecordData::value_type Record[] = {DECL_CONTEXT_LEXICAL}; 2902 1.1 joerg Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, 2903 1.1 joerg bytes(KindDeclPairs)); 2904 1.1 joerg return Offset; 2905 1.1 joerg } 2906 1.1 joerg 2907 1.1 joerg void ASTWriter::WriteTypeDeclOffsets() { 2908 1.1 joerg using namespace llvm; 2909 1.1 joerg 2910 1.1 joerg // Write the type offsets array 2911 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2912 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET)); 2913 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types 2914 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base type index 2915 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block 2916 1.1 joerg unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2917 1.1 joerg { 2918 1.1 joerg RecordData::value_type Record[] = {TYPE_OFFSET, TypeOffsets.size(), 2919 1.1 joerg FirstTypeID - NUM_PREDEF_TYPE_IDS}; 2920 1.1 joerg Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, bytes(TypeOffsets)); 2921 1.1 joerg } 2922 1.1 joerg 2923 1.1 joerg // Write the declaration offsets array 2924 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 2925 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); 2926 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations 2927 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID 2928 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block 2929 1.1 joerg unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 2930 1.1 joerg { 2931 1.1 joerg RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), 2932 1.1 joerg FirstDeclID - NUM_PREDEF_DECL_IDS}; 2933 1.1 joerg Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); 2934 1.1 joerg } 2935 1.1 joerg } 2936 1.1 joerg 2937 1.1 joerg void ASTWriter::WriteFileDeclIDsMap() { 2938 1.1 joerg using namespace llvm; 2939 1.1 joerg 2940 1.1.1.2 joerg SmallVector<std::pair<FileID, DeclIDInFileInfo *>, 64> SortedFileDeclIDs; 2941 1.1.1.2 joerg SortedFileDeclIDs.reserve(FileDeclIDs.size()); 2942 1.1.1.2 joerg for (const auto &P : FileDeclIDs) 2943 1.1.1.2 joerg SortedFileDeclIDs.push_back(std::make_pair(P.first, P.second.get())); 2944 1.1 joerg llvm::sort(SortedFileDeclIDs, llvm::less_first()); 2945 1.1 joerg 2946 1.1 joerg // Join the vectors of DeclIDs from all files. 2947 1.1 joerg SmallVector<DeclID, 256> FileGroupedDeclIDs; 2948 1.1 joerg for (auto &FileDeclEntry : SortedFileDeclIDs) { 2949 1.1 joerg DeclIDInFileInfo &Info = *FileDeclEntry.second; 2950 1.1 joerg Info.FirstDeclIndex = FileGroupedDeclIDs.size(); 2951 1.1 joerg for (auto &LocDeclEntry : Info.DeclIDs) 2952 1.1 joerg FileGroupedDeclIDs.push_back(LocDeclEntry.second); 2953 1.1 joerg } 2954 1.1 joerg 2955 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 2956 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(FILE_SORTED_DECLS)); 2957 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 2958 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 2959 1.1 joerg unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev)); 2960 1.1 joerg RecordData::value_type Record[] = {FILE_SORTED_DECLS, 2961 1.1 joerg FileGroupedDeclIDs.size()}; 2962 1.1 joerg Stream.EmitRecordWithBlob(AbbrevCode, Record, bytes(FileGroupedDeclIDs)); 2963 1.1 joerg } 2964 1.1 joerg 2965 1.1 joerg void ASTWriter::WriteComments() { 2966 1.1 joerg Stream.EnterSubblock(COMMENTS_BLOCK_ID, 3); 2967 1.1 joerg auto _ = llvm::make_scope_exit([this] { Stream.ExitBlock(); }); 2968 1.1 joerg if (!PP->getPreprocessorOpts().WriteCommentListToPCH) 2969 1.1 joerg return; 2970 1.1 joerg RecordData Record; 2971 1.1 joerg for (const auto &FO : Context->Comments.OrderedComments) { 2972 1.1 joerg for (const auto &OC : FO.second) { 2973 1.1 joerg const RawComment *I = OC.second; 2974 1.1 joerg Record.clear(); 2975 1.1 joerg AddSourceRange(I->getSourceRange(), Record); 2976 1.1 joerg Record.push_back(I->getKind()); 2977 1.1 joerg Record.push_back(I->isTrailingComment()); 2978 1.1 joerg Record.push_back(I->isAlmostTrailingComment()); 2979 1.1 joerg Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record); 2980 1.1 joerg } 2981 1.1 joerg } 2982 1.1 joerg } 2983 1.1 joerg 2984 1.1 joerg //===----------------------------------------------------------------------===// 2985 1.1 joerg // Global Method Pool and Selector Serialization 2986 1.1 joerg //===----------------------------------------------------------------------===// 2987 1.1 joerg 2988 1.1 joerg namespace { 2989 1.1 joerg 2990 1.1 joerg // Trait used for the on-disk hash table used in the method pool. 2991 1.1 joerg class ASTMethodPoolTrait { 2992 1.1 joerg ASTWriter &Writer; 2993 1.1 joerg 2994 1.1 joerg public: 2995 1.1 joerg using key_type = Selector; 2996 1.1 joerg using key_type_ref = key_type; 2997 1.1 joerg 2998 1.1 joerg struct data_type { 2999 1.1 joerg SelectorID ID; 3000 1.1 joerg ObjCMethodList Instance, Factory; 3001 1.1 joerg }; 3002 1.1 joerg using data_type_ref = const data_type &; 3003 1.1 joerg 3004 1.1 joerg using hash_value_type = unsigned; 3005 1.1 joerg using offset_type = unsigned; 3006 1.1 joerg 3007 1.1 joerg explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) {} 3008 1.1 joerg 3009 1.1 joerg static hash_value_type ComputeHash(Selector Sel) { 3010 1.1 joerg return serialization::ComputeHash(Sel); 3011 1.1 joerg } 3012 1.1 joerg 3013 1.1 joerg std::pair<unsigned, unsigned> 3014 1.1 joerg EmitKeyDataLength(raw_ostream& Out, Selector Sel, 3015 1.1 joerg data_type_ref Methods) { 3016 1.1 joerg unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4); 3017 1.1 joerg unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts 3018 1.1 joerg for (const ObjCMethodList *Method = &Methods.Instance; Method; 3019 1.1 joerg Method = Method->getNext()) 3020 1.1 joerg if (Method->getMethod()) 3021 1.1 joerg DataLen += 4; 3022 1.1 joerg for (const ObjCMethodList *Method = &Methods.Factory; Method; 3023 1.1 joerg Method = Method->getNext()) 3024 1.1 joerg if (Method->getMethod()) 3025 1.1 joerg DataLen += 4; 3026 1.1.1.2 joerg return emitULEBKeyDataLength(KeyLen, DataLen, Out); 3027 1.1 joerg } 3028 1.1 joerg 3029 1.1 joerg void EmitKey(raw_ostream& Out, Selector Sel, unsigned) { 3030 1.1 joerg using namespace llvm::support; 3031 1.1 joerg 3032 1.1 joerg endian::Writer LE(Out, little); 3033 1.1 joerg uint64_t Start = Out.tell(); 3034 1.1 joerg assert((Start >> 32) == 0 && "Selector key offset too large"); 3035 1.1 joerg Writer.SetSelectorOffset(Sel, Start); 3036 1.1 joerg unsigned N = Sel.getNumArgs(); 3037 1.1 joerg LE.write<uint16_t>(N); 3038 1.1 joerg if (N == 0) 3039 1.1 joerg N = 1; 3040 1.1 joerg for (unsigned I = 0; I != N; ++I) 3041 1.1 joerg LE.write<uint32_t>( 3042 1.1 joerg Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I))); 3043 1.1 joerg } 3044 1.1 joerg 3045 1.1 joerg void EmitData(raw_ostream& Out, key_type_ref, 3046 1.1 joerg data_type_ref Methods, unsigned DataLen) { 3047 1.1 joerg using namespace llvm::support; 3048 1.1 joerg 3049 1.1 joerg endian::Writer LE(Out, little); 3050 1.1 joerg uint64_t Start = Out.tell(); (void)Start; 3051 1.1 joerg LE.write<uint32_t>(Methods.ID); 3052 1.1 joerg unsigned NumInstanceMethods = 0; 3053 1.1 joerg for (const ObjCMethodList *Method = &Methods.Instance; Method; 3054 1.1 joerg Method = Method->getNext()) 3055 1.1 joerg if (Method->getMethod()) 3056 1.1 joerg ++NumInstanceMethods; 3057 1.1 joerg 3058 1.1 joerg unsigned NumFactoryMethods = 0; 3059 1.1 joerg for (const ObjCMethodList *Method = &Methods.Factory; Method; 3060 1.1 joerg Method = Method->getNext()) 3061 1.1 joerg if (Method->getMethod()) 3062 1.1 joerg ++NumFactoryMethods; 3063 1.1 joerg 3064 1.1 joerg unsigned InstanceBits = Methods.Instance.getBits(); 3065 1.1 joerg assert(InstanceBits < 4); 3066 1.1 joerg unsigned InstanceHasMoreThanOneDeclBit = 3067 1.1 joerg Methods.Instance.hasMoreThanOneDecl(); 3068 1.1 joerg unsigned FullInstanceBits = (NumInstanceMethods << 3) | 3069 1.1 joerg (InstanceHasMoreThanOneDeclBit << 2) | 3070 1.1 joerg InstanceBits; 3071 1.1 joerg unsigned FactoryBits = Methods.Factory.getBits(); 3072 1.1 joerg assert(FactoryBits < 4); 3073 1.1 joerg unsigned FactoryHasMoreThanOneDeclBit = 3074 1.1 joerg Methods.Factory.hasMoreThanOneDecl(); 3075 1.1 joerg unsigned FullFactoryBits = (NumFactoryMethods << 3) | 3076 1.1 joerg (FactoryHasMoreThanOneDeclBit << 2) | 3077 1.1 joerg FactoryBits; 3078 1.1 joerg LE.write<uint16_t>(FullInstanceBits); 3079 1.1 joerg LE.write<uint16_t>(FullFactoryBits); 3080 1.1 joerg for (const ObjCMethodList *Method = &Methods.Instance; Method; 3081 1.1 joerg Method = Method->getNext()) 3082 1.1 joerg if (Method->getMethod()) 3083 1.1 joerg LE.write<uint32_t>(Writer.getDeclID(Method->getMethod())); 3084 1.1 joerg for (const ObjCMethodList *Method = &Methods.Factory; Method; 3085 1.1 joerg Method = Method->getNext()) 3086 1.1 joerg if (Method->getMethod()) 3087 1.1 joerg LE.write<uint32_t>(Writer.getDeclID(Method->getMethod())); 3088 1.1 joerg 3089 1.1 joerg assert(Out.tell() - Start == DataLen && "Data length is wrong"); 3090 1.1 joerg } 3091 1.1 joerg }; 3092 1.1 joerg 3093 1.1 joerg } // namespace 3094 1.1 joerg 3095 1.1 joerg /// Write ObjC data: selectors and the method pool. 3096 1.1 joerg /// 3097 1.1 joerg /// The method pool contains both instance and factory methods, stored 3098 1.1 joerg /// in an on-disk hash table indexed by the selector. The hash table also 3099 1.1 joerg /// contains an empty entry for every other selector known to Sema. 3100 1.1 joerg void ASTWriter::WriteSelectors(Sema &SemaRef) { 3101 1.1 joerg using namespace llvm; 3102 1.1 joerg 3103 1.1 joerg // Do we have to do anything at all? 3104 1.1 joerg if (SemaRef.MethodPool.empty() && SelectorIDs.empty()) 3105 1.1 joerg return; 3106 1.1 joerg unsigned NumTableEntries = 0; 3107 1.1 joerg // Create and write out the blob that contains selectors and the method pool. 3108 1.1 joerg { 3109 1.1 joerg llvm::OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator; 3110 1.1 joerg ASTMethodPoolTrait Trait(*this); 3111 1.1 joerg 3112 1.1 joerg // Create the on-disk hash table representation. We walk through every 3113 1.1 joerg // selector we've seen and look it up in the method pool. 3114 1.1 joerg SelectorOffsets.resize(NextSelectorID - FirstSelectorID); 3115 1.1 joerg for (auto &SelectorAndID : SelectorIDs) { 3116 1.1 joerg Selector S = SelectorAndID.first; 3117 1.1 joerg SelectorID ID = SelectorAndID.second; 3118 1.1 joerg Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); 3119 1.1 joerg ASTMethodPoolTrait::data_type Data = { 3120 1.1 joerg ID, 3121 1.1 joerg ObjCMethodList(), 3122 1.1 joerg ObjCMethodList() 3123 1.1 joerg }; 3124 1.1 joerg if (F != SemaRef.MethodPool.end()) { 3125 1.1 joerg Data.Instance = F->second.first; 3126 1.1 joerg Data.Factory = F->second.second; 3127 1.1 joerg } 3128 1.1 joerg // Only write this selector if it's not in an existing AST or something 3129 1.1 joerg // changed. 3130 1.1 joerg if (Chain && ID < FirstSelectorID) { 3131 1.1 joerg // Selector already exists. Did it change? 3132 1.1 joerg bool changed = false; 3133 1.1 joerg for (ObjCMethodList *M = &Data.Instance; 3134 1.1 joerg !changed && M && M->getMethod(); M = M->getNext()) { 3135 1.1 joerg if (!M->getMethod()->isFromASTFile()) 3136 1.1 joerg changed = true; 3137 1.1 joerg } 3138 1.1 joerg for (ObjCMethodList *M = &Data.Factory; !changed && M && M->getMethod(); 3139 1.1 joerg M = M->getNext()) { 3140 1.1 joerg if (!M->getMethod()->isFromASTFile()) 3141 1.1 joerg changed = true; 3142 1.1 joerg } 3143 1.1 joerg if (!changed) 3144 1.1 joerg continue; 3145 1.1 joerg } else if (Data.Instance.getMethod() || Data.Factory.getMethod()) { 3146 1.1 joerg // A new method pool entry. 3147 1.1 joerg ++NumTableEntries; 3148 1.1 joerg } 3149 1.1 joerg Generator.insert(S, Data, Trait); 3150 1.1 joerg } 3151 1.1 joerg 3152 1.1 joerg // Create the on-disk hash table in a buffer. 3153 1.1 joerg SmallString<4096> MethodPool; 3154 1.1 joerg uint32_t BucketOffset; 3155 1.1 joerg { 3156 1.1 joerg using namespace llvm::support; 3157 1.1 joerg 3158 1.1 joerg ASTMethodPoolTrait Trait(*this); 3159 1.1 joerg llvm::raw_svector_ostream Out(MethodPool); 3160 1.1 joerg // Make sure that no bucket is at offset 0 3161 1.1 joerg endian::write<uint32_t>(Out, 0, little); 3162 1.1 joerg BucketOffset = Generator.Emit(Out, Trait); 3163 1.1 joerg } 3164 1.1 joerg 3165 1.1 joerg // Create a blob abbreviation 3166 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 3167 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL)); 3168 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 3169 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 3170 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 3171 1.1 joerg unsigned MethodPoolAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 3172 1.1 joerg 3173 1.1 joerg // Write the method pool 3174 1.1 joerg { 3175 1.1 joerg RecordData::value_type Record[] = {METHOD_POOL, BucketOffset, 3176 1.1 joerg NumTableEntries}; 3177 1.1 joerg Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool); 3178 1.1 joerg } 3179 1.1 joerg 3180 1.1 joerg // Create a blob abbreviation for the selector table offsets. 3181 1.1 joerg Abbrev = std::make_shared<BitCodeAbbrev>(); 3182 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS)); 3183 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size 3184 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID 3185 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 3186 1.1 joerg unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 3187 1.1 joerg 3188 1.1 joerg // Write the selector offsets table. 3189 1.1 joerg { 3190 1.1 joerg RecordData::value_type Record[] = { 3191 1.1 joerg SELECTOR_OFFSETS, SelectorOffsets.size(), 3192 1.1 joerg FirstSelectorID - NUM_PREDEF_SELECTOR_IDS}; 3193 1.1 joerg Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, 3194 1.1 joerg bytes(SelectorOffsets)); 3195 1.1 joerg } 3196 1.1 joerg } 3197 1.1 joerg } 3198 1.1 joerg 3199 1.1 joerg /// Write the selectors referenced in @selector expression into AST file. 3200 1.1 joerg void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { 3201 1.1 joerg using namespace llvm; 3202 1.1 joerg 3203 1.1 joerg if (SemaRef.ReferencedSelectors.empty()) 3204 1.1 joerg return; 3205 1.1 joerg 3206 1.1 joerg RecordData Record; 3207 1.1 joerg ASTRecordWriter Writer(*this, Record); 3208 1.1 joerg 3209 1.1 joerg // Note: this writes out all references even for a dependent AST. But it is 3210 1.1 joerg // very tricky to fix, and given that @selector shouldn't really appear in 3211 1.1 joerg // headers, probably not worth it. It's not a correctness issue. 3212 1.1 joerg for (auto &SelectorAndLocation : SemaRef.ReferencedSelectors) { 3213 1.1 joerg Selector Sel = SelectorAndLocation.first; 3214 1.1 joerg SourceLocation Loc = SelectorAndLocation.second; 3215 1.1 joerg Writer.AddSelectorRef(Sel); 3216 1.1 joerg Writer.AddSourceLocation(Loc); 3217 1.1 joerg } 3218 1.1 joerg Writer.Emit(REFERENCED_SELECTOR_POOL); 3219 1.1 joerg } 3220 1.1 joerg 3221 1.1 joerg //===----------------------------------------------------------------------===// 3222 1.1 joerg // Identifier Table Serialization 3223 1.1 joerg //===----------------------------------------------------------------------===// 3224 1.1 joerg 3225 1.1 joerg /// Determine the declaration that should be put into the name lookup table to 3226 1.1 joerg /// represent the given declaration in this module. This is usually D itself, 3227 1.1 joerg /// but if D was imported and merged into a local declaration, we want the most 3228 1.1 joerg /// recent local declaration instead. The chosen declaration will be the most 3229 1.1 joerg /// recent declaration in any module that imports this one. 3230 1.1 joerg static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts, 3231 1.1 joerg NamedDecl *D) { 3232 1.1 joerg if (!LangOpts.Modules || !D->isFromASTFile()) 3233 1.1 joerg return D; 3234 1.1 joerg 3235 1.1 joerg if (Decl *Redecl = D->getPreviousDecl()) { 3236 1.1 joerg // For Redeclarable decls, a prior declaration might be local. 3237 1.1 joerg for (; Redecl; Redecl = Redecl->getPreviousDecl()) { 3238 1.1 joerg // If we find a local decl, we're done. 3239 1.1 joerg if (!Redecl->isFromASTFile()) { 3240 1.1 joerg // Exception: in very rare cases (for injected-class-names), not all 3241 1.1 joerg // redeclarations are in the same semantic context. Skip ones in a 3242 1.1 joerg // different context. They don't go in this lookup table at all. 3243 1.1 joerg if (!Redecl->getDeclContext()->getRedeclContext()->Equals( 3244 1.1 joerg D->getDeclContext()->getRedeclContext())) 3245 1.1 joerg continue; 3246 1.1 joerg return cast<NamedDecl>(Redecl); 3247 1.1 joerg } 3248 1.1 joerg 3249 1.1 joerg // If we find a decl from a (chained-)PCH stop since we won't find a 3250 1.1 joerg // local one. 3251 1.1 joerg if (Redecl->getOwningModuleID() == 0) 3252 1.1 joerg break; 3253 1.1 joerg } 3254 1.1 joerg } else if (Decl *First = D->getCanonicalDecl()) { 3255 1.1 joerg // For Mergeable decls, the first decl might be local. 3256 1.1 joerg if (!First->isFromASTFile()) 3257 1.1 joerg return cast<NamedDecl>(First); 3258 1.1 joerg } 3259 1.1 joerg 3260 1.1 joerg // All declarations are imported. Our most recent declaration will also be 3261 1.1 joerg // the most recent one in anyone who imports us. 3262 1.1 joerg return D; 3263 1.1 joerg } 3264 1.1 joerg 3265 1.1 joerg namespace { 3266 1.1 joerg 3267 1.1 joerg class ASTIdentifierTableTrait { 3268 1.1 joerg ASTWriter &Writer; 3269 1.1 joerg Preprocessor &PP; 3270 1.1 joerg IdentifierResolver &IdResolver; 3271 1.1 joerg bool IsModule; 3272 1.1 joerg bool NeedDecls; 3273 1.1 joerg ASTWriter::RecordData *InterestingIdentifierOffsets; 3274 1.1 joerg 3275 1.1 joerg /// Determines whether this is an "interesting" identifier that needs a 3276 1.1 joerg /// full IdentifierInfo structure written into the hash table. Notably, this 3277 1.1 joerg /// doesn't check whether the name has macros defined; use PublicMacroIterator 3278 1.1 joerg /// to check that. 3279 1.1 joerg bool isInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset) { 3280 1.1.1.2 joerg if (MacroOffset || II->isPoisoned() || 3281 1.1.1.2 joerg (!IsModule && II->getObjCOrBuiltinID()) || 3282 1.1 joerg II->hasRevertedTokenIDToIdentifier() || 3283 1.1 joerg (NeedDecls && II->getFETokenInfo())) 3284 1.1 joerg return true; 3285 1.1 joerg 3286 1.1 joerg return false; 3287 1.1 joerg } 3288 1.1 joerg 3289 1.1 joerg public: 3290 1.1 joerg using key_type = IdentifierInfo *; 3291 1.1 joerg using key_type_ref = key_type; 3292 1.1 joerg 3293 1.1 joerg using data_type = IdentID; 3294 1.1 joerg using data_type_ref = data_type; 3295 1.1 joerg 3296 1.1 joerg using hash_value_type = unsigned; 3297 1.1 joerg using offset_type = unsigned; 3298 1.1 joerg 3299 1.1 joerg ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP, 3300 1.1 joerg IdentifierResolver &IdResolver, bool IsModule, 3301 1.1 joerg ASTWriter::RecordData *InterestingIdentifierOffsets) 3302 1.1 joerg : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule), 3303 1.1 joerg NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus), 3304 1.1 joerg InterestingIdentifierOffsets(InterestingIdentifierOffsets) {} 3305 1.1 joerg 3306 1.1 joerg bool needDecls() const { return NeedDecls; } 3307 1.1 joerg 3308 1.1 joerg static hash_value_type ComputeHash(const IdentifierInfo* II) { 3309 1.1 joerg return llvm::djbHash(II->getName()); 3310 1.1 joerg } 3311 1.1 joerg 3312 1.1 joerg bool isInterestingIdentifier(const IdentifierInfo *II) { 3313 1.1 joerg auto MacroOffset = Writer.getMacroDirectivesOffset(II); 3314 1.1 joerg return isInterestingIdentifier(II, MacroOffset); 3315 1.1 joerg } 3316 1.1 joerg 3317 1.1 joerg bool isInterestingNonMacroIdentifier(const IdentifierInfo *II) { 3318 1.1 joerg return isInterestingIdentifier(II, 0); 3319 1.1 joerg } 3320 1.1 joerg 3321 1.1 joerg std::pair<unsigned, unsigned> 3322 1.1 joerg EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) { 3323 1.1.1.2 joerg // Record the location of the identifier data. This is used when generating 3324 1.1.1.2 joerg // the mapping from persistent IDs to strings. 3325 1.1.1.2 joerg Writer.SetIdentifierOffset(II, Out.tell()); 3326 1.1.1.2 joerg 3327 1.1.1.2 joerg // Emit the offset of the key/data length information to the interesting 3328 1.1.1.2 joerg // identifiers table if necessary. 3329 1.1.1.2 joerg if (InterestingIdentifierOffsets && isInterestingIdentifier(II)) 3330 1.1.1.2 joerg InterestingIdentifierOffsets->push_back(Out.tell()); 3331 1.1.1.2 joerg 3332 1.1 joerg unsigned KeyLen = II->getLength() + 1; 3333 1.1 joerg unsigned DataLen = 4; // 4 bytes for the persistent ID << 1 3334 1.1 joerg auto MacroOffset = Writer.getMacroDirectivesOffset(II); 3335 1.1 joerg if (isInterestingIdentifier(II, MacroOffset)) { 3336 1.1 joerg DataLen += 2; // 2 bytes for builtin ID 3337 1.1 joerg DataLen += 2; // 2 bytes for flags 3338 1.1 joerg if (MacroOffset) 3339 1.1 joerg DataLen += 4; // MacroDirectives offset. 3340 1.1 joerg 3341 1.1 joerg if (NeedDecls) { 3342 1.1 joerg for (IdentifierResolver::iterator D = IdResolver.begin(II), 3343 1.1 joerg DEnd = IdResolver.end(); 3344 1.1 joerg D != DEnd; ++D) 3345 1.1 joerg DataLen += 4; 3346 1.1 joerg } 3347 1.1 joerg } 3348 1.1.1.2 joerg return emitULEBKeyDataLength(KeyLen, DataLen, Out); 3349 1.1 joerg } 3350 1.1 joerg 3351 1.1 joerg void EmitKey(raw_ostream& Out, const IdentifierInfo* II, 3352 1.1 joerg unsigned KeyLen) { 3353 1.1 joerg Out.write(II->getNameStart(), KeyLen); 3354 1.1 joerg } 3355 1.1 joerg 3356 1.1 joerg void EmitData(raw_ostream& Out, IdentifierInfo* II, 3357 1.1 joerg IdentID ID, unsigned) { 3358 1.1 joerg using namespace llvm::support; 3359 1.1 joerg 3360 1.1 joerg endian::Writer LE(Out, little); 3361 1.1 joerg 3362 1.1 joerg auto MacroOffset = Writer.getMacroDirectivesOffset(II); 3363 1.1 joerg if (!isInterestingIdentifier(II, MacroOffset)) { 3364 1.1 joerg LE.write<uint32_t>(ID << 1); 3365 1.1 joerg return; 3366 1.1 joerg } 3367 1.1 joerg 3368 1.1 joerg LE.write<uint32_t>((ID << 1) | 0x01); 3369 1.1 joerg uint32_t Bits = (uint32_t)II->getObjCOrBuiltinID(); 3370 1.1 joerg assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader."); 3371 1.1 joerg LE.write<uint16_t>(Bits); 3372 1.1 joerg Bits = 0; 3373 1.1 joerg bool HadMacroDefinition = MacroOffset != 0; 3374 1.1 joerg Bits = (Bits << 1) | unsigned(HadMacroDefinition); 3375 1.1 joerg Bits = (Bits << 1) | unsigned(II->isExtensionToken()); 3376 1.1 joerg Bits = (Bits << 1) | unsigned(II->isPoisoned()); 3377 1.1 joerg Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier()); 3378 1.1 joerg Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword()); 3379 1.1 joerg LE.write<uint16_t>(Bits); 3380 1.1 joerg 3381 1.1 joerg if (HadMacroDefinition) 3382 1.1 joerg LE.write<uint32_t>(MacroOffset); 3383 1.1 joerg 3384 1.1 joerg if (NeedDecls) { 3385 1.1 joerg // Emit the declaration IDs in reverse order, because the 3386 1.1 joerg // IdentifierResolver provides the declarations as they would be 3387 1.1 joerg // visible (e.g., the function "stat" would come before the struct 3388 1.1 joerg // "stat"), but the ASTReader adds declarations to the end of the list 3389 1.1 joerg // (so we need to see the struct "stat" before the function "stat"). 3390 1.1 joerg // Only emit declarations that aren't from a chained PCH, though. 3391 1.1 joerg SmallVector<NamedDecl *, 16> Decls(IdResolver.begin(II), 3392 1.1 joerg IdResolver.end()); 3393 1.1 joerg for (SmallVectorImpl<NamedDecl *>::reverse_iterator D = Decls.rbegin(), 3394 1.1 joerg DEnd = Decls.rend(); 3395 1.1 joerg D != DEnd; ++D) 3396 1.1 joerg LE.write<uint32_t>( 3397 1.1 joerg Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), *D))); 3398 1.1 joerg } 3399 1.1 joerg } 3400 1.1 joerg }; 3401 1.1 joerg 3402 1.1 joerg } // namespace 3403 1.1 joerg 3404 1.1 joerg /// Write the identifier table into the AST file. 3405 1.1 joerg /// 3406 1.1 joerg /// The identifier table consists of a blob containing string data 3407 1.1 joerg /// (the actual identifiers themselves) and a separate "offsets" index 3408 1.1 joerg /// that maps identifier IDs to locations within the blob. 3409 1.1 joerg void ASTWriter::WriteIdentifierTable(Preprocessor &PP, 3410 1.1 joerg IdentifierResolver &IdResolver, 3411 1.1 joerg bool IsModule) { 3412 1.1 joerg using namespace llvm; 3413 1.1 joerg 3414 1.1 joerg RecordData InterestingIdents; 3415 1.1 joerg 3416 1.1 joerg // Create and write out the blob that contains the identifier 3417 1.1 joerg // strings. 3418 1.1 joerg { 3419 1.1 joerg llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; 3420 1.1 joerg ASTIdentifierTableTrait Trait( 3421 1.1 joerg *this, PP, IdResolver, IsModule, 3422 1.1 joerg (getLangOpts().CPlusPlus && IsModule) ? &InterestingIdents : nullptr); 3423 1.1 joerg 3424 1.1 joerg // Look for any identifiers that were named while processing the 3425 1.1 joerg // headers, but are otherwise not needed. We add these to the hash 3426 1.1 joerg // table to enable checking of the predefines buffer in the case 3427 1.1 joerg // where the user adds new macro definitions when building the AST 3428 1.1 joerg // file. 3429 1.1 joerg SmallVector<const IdentifierInfo *, 128> IIs; 3430 1.1 joerg for (const auto &ID : PP.getIdentifierTable()) 3431 1.1 joerg IIs.push_back(ID.second); 3432 1.1 joerg // Sort the identifiers lexicographically before getting them references so 3433 1.1 joerg // that their order is stable. 3434 1.1 joerg llvm::sort(IIs, llvm::deref<std::less<>>()); 3435 1.1 joerg for (const IdentifierInfo *II : IIs) 3436 1.1 joerg if (Trait.isInterestingNonMacroIdentifier(II)) 3437 1.1 joerg getIdentifierRef(II); 3438 1.1 joerg 3439 1.1 joerg // Create the on-disk hash table representation. We only store offsets 3440 1.1 joerg // for identifiers that appear here for the first time. 3441 1.1 joerg IdentifierOffsets.resize(NextIdentID - FirstIdentID); 3442 1.1 joerg for (auto IdentIDPair : IdentifierIDs) { 3443 1.1 joerg auto *II = const_cast<IdentifierInfo *>(IdentIDPair.first); 3444 1.1 joerg IdentID ID = IdentIDPair.second; 3445 1.1 joerg assert(II && "NULL identifier in identifier table"); 3446 1.1 joerg // Write out identifiers if either the ID is local or the identifier has 3447 1.1 joerg // changed since it was loaded. 3448 1.1 joerg if (ID >= FirstIdentID || !Chain || !II->isFromAST() 3449 1.1 joerg || II->hasChangedSinceDeserialization() || 3450 1.1 joerg (Trait.needDecls() && 3451 1.1 joerg II->hasFETokenInfoChangedSinceDeserialization())) 3452 1.1 joerg Generator.insert(II, ID, Trait); 3453 1.1 joerg } 3454 1.1 joerg 3455 1.1 joerg // Create the on-disk hash table in a buffer. 3456 1.1 joerg SmallString<4096> IdentifierTable; 3457 1.1 joerg uint32_t BucketOffset; 3458 1.1 joerg { 3459 1.1 joerg using namespace llvm::support; 3460 1.1 joerg 3461 1.1 joerg llvm::raw_svector_ostream Out(IdentifierTable); 3462 1.1 joerg // Make sure that no bucket is at offset 0 3463 1.1 joerg endian::write<uint32_t>(Out, 0, little); 3464 1.1 joerg BucketOffset = Generator.Emit(Out, Trait); 3465 1.1 joerg } 3466 1.1 joerg 3467 1.1 joerg // Create a blob abbreviation 3468 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 3469 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE)); 3470 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 3471 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 3472 1.1 joerg unsigned IDTableAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 3473 1.1 joerg 3474 1.1 joerg // Write the identifier table 3475 1.1 joerg RecordData::value_type Record[] = {IDENTIFIER_TABLE, BucketOffset}; 3476 1.1 joerg Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable); 3477 1.1 joerg } 3478 1.1 joerg 3479 1.1 joerg // Write the offsets table for identifier IDs. 3480 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 3481 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET)); 3482 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers 3483 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID 3484 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 3485 1.1 joerg unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 3486 1.1 joerg 3487 1.1 joerg #ifndef NDEBUG 3488 1.1 joerg for (unsigned I = 0, N = IdentifierOffsets.size(); I != N; ++I) 3489 1.1 joerg assert(IdentifierOffsets[I] && "Missing identifier offset?"); 3490 1.1 joerg #endif 3491 1.1 joerg 3492 1.1 joerg RecordData::value_type Record[] = {IDENTIFIER_OFFSET, 3493 1.1 joerg IdentifierOffsets.size(), 3494 1.1 joerg FirstIdentID - NUM_PREDEF_IDENT_IDS}; 3495 1.1 joerg Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, 3496 1.1 joerg bytes(IdentifierOffsets)); 3497 1.1 joerg 3498 1.1 joerg // In C++, write the list of interesting identifiers (those that are 3499 1.1 joerg // defined as macros, poisoned, or similar unusual things). 3500 1.1 joerg if (!InterestingIdents.empty()) 3501 1.1 joerg Stream.EmitRecord(INTERESTING_IDENTIFIERS, InterestingIdents); 3502 1.1 joerg } 3503 1.1 joerg 3504 1.1 joerg //===----------------------------------------------------------------------===// 3505 1.1 joerg // DeclContext's Name Lookup Table Serialization 3506 1.1 joerg //===----------------------------------------------------------------------===// 3507 1.1 joerg 3508 1.1 joerg namespace { 3509 1.1 joerg 3510 1.1 joerg // Trait used for the on-disk hash table used in the method pool. 3511 1.1 joerg class ASTDeclContextNameLookupTrait { 3512 1.1 joerg ASTWriter &Writer; 3513 1.1 joerg llvm::SmallVector<DeclID, 64> DeclIDs; 3514 1.1 joerg 3515 1.1 joerg public: 3516 1.1 joerg using key_type = DeclarationNameKey; 3517 1.1 joerg using key_type_ref = key_type; 3518 1.1 joerg 3519 1.1 joerg /// A start and end index into DeclIDs, representing a sequence of decls. 3520 1.1 joerg using data_type = std::pair<unsigned, unsigned>; 3521 1.1 joerg using data_type_ref = const data_type &; 3522 1.1 joerg 3523 1.1 joerg using hash_value_type = unsigned; 3524 1.1 joerg using offset_type = unsigned; 3525 1.1 joerg 3526 1.1 joerg explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) {} 3527 1.1 joerg 3528 1.1 joerg template<typename Coll> 3529 1.1 joerg data_type getData(const Coll &Decls) { 3530 1.1 joerg unsigned Start = DeclIDs.size(); 3531 1.1 joerg for (NamedDecl *D : Decls) { 3532 1.1 joerg DeclIDs.push_back( 3533 1.1 joerg Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), D))); 3534 1.1 joerg } 3535 1.1 joerg return std::make_pair(Start, DeclIDs.size()); 3536 1.1 joerg } 3537 1.1 joerg 3538 1.1 joerg data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) { 3539 1.1 joerg unsigned Start = DeclIDs.size(); 3540 1.1 joerg for (auto ID : FromReader) 3541 1.1 joerg DeclIDs.push_back(ID); 3542 1.1 joerg return std::make_pair(Start, DeclIDs.size()); 3543 1.1 joerg } 3544 1.1 joerg 3545 1.1 joerg static bool EqualKey(key_type_ref a, key_type_ref b) { 3546 1.1 joerg return a == b; 3547 1.1 joerg } 3548 1.1 joerg 3549 1.1 joerg hash_value_type ComputeHash(DeclarationNameKey Name) { 3550 1.1 joerg return Name.getHash(); 3551 1.1 joerg } 3552 1.1 joerg 3553 1.1 joerg void EmitFileRef(raw_ostream &Out, ModuleFile *F) const { 3554 1.1 joerg assert(Writer.hasChain() && 3555 1.1 joerg "have reference to loaded module file but no chain?"); 3556 1.1 joerg 3557 1.1 joerg using namespace llvm::support; 3558 1.1 joerg 3559 1.1 joerg endian::write<uint32_t>(Out, Writer.getChain()->getModuleFileID(F), little); 3560 1.1 joerg } 3561 1.1 joerg 3562 1.1 joerg std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out, 3563 1.1 joerg DeclarationNameKey Name, 3564 1.1 joerg data_type_ref Lookup) { 3565 1.1 joerg unsigned KeyLen = 1; 3566 1.1 joerg switch (Name.getKind()) { 3567 1.1 joerg case DeclarationName::Identifier: 3568 1.1 joerg case DeclarationName::ObjCZeroArgSelector: 3569 1.1 joerg case DeclarationName::ObjCOneArgSelector: 3570 1.1 joerg case DeclarationName::ObjCMultiArgSelector: 3571 1.1 joerg case DeclarationName::CXXLiteralOperatorName: 3572 1.1 joerg case DeclarationName::CXXDeductionGuideName: 3573 1.1 joerg KeyLen += 4; 3574 1.1 joerg break; 3575 1.1 joerg case DeclarationName::CXXOperatorName: 3576 1.1 joerg KeyLen += 1; 3577 1.1 joerg break; 3578 1.1 joerg case DeclarationName::CXXConstructorName: 3579 1.1 joerg case DeclarationName::CXXDestructorName: 3580 1.1 joerg case DeclarationName::CXXConversionFunctionName: 3581 1.1 joerg case DeclarationName::CXXUsingDirective: 3582 1.1 joerg break; 3583 1.1 joerg } 3584 1.1 joerg 3585 1.1 joerg // 4 bytes for each DeclID. 3586 1.1 joerg unsigned DataLen = 4 * (Lookup.second - Lookup.first); 3587 1.1 joerg 3588 1.1.1.2 joerg return emitULEBKeyDataLength(KeyLen, DataLen, Out); 3589 1.1 joerg } 3590 1.1 joerg 3591 1.1 joerg void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) { 3592 1.1 joerg using namespace llvm::support; 3593 1.1 joerg 3594 1.1 joerg endian::Writer LE(Out, little); 3595 1.1 joerg LE.write<uint8_t>(Name.getKind()); 3596 1.1 joerg switch (Name.getKind()) { 3597 1.1 joerg case DeclarationName::Identifier: 3598 1.1 joerg case DeclarationName::CXXLiteralOperatorName: 3599 1.1 joerg case DeclarationName::CXXDeductionGuideName: 3600 1.1 joerg LE.write<uint32_t>(Writer.getIdentifierRef(Name.getIdentifier())); 3601 1.1 joerg return; 3602 1.1 joerg case DeclarationName::ObjCZeroArgSelector: 3603 1.1 joerg case DeclarationName::ObjCOneArgSelector: 3604 1.1 joerg case DeclarationName::ObjCMultiArgSelector: 3605 1.1 joerg LE.write<uint32_t>(Writer.getSelectorRef(Name.getSelector())); 3606 1.1 joerg return; 3607 1.1 joerg case DeclarationName::CXXOperatorName: 3608 1.1 joerg assert(Name.getOperatorKind() < NUM_OVERLOADED_OPERATORS && 3609 1.1 joerg "Invalid operator?"); 3610 1.1 joerg LE.write<uint8_t>(Name.getOperatorKind()); 3611 1.1 joerg return; 3612 1.1 joerg case DeclarationName::CXXConstructorName: 3613 1.1 joerg case DeclarationName::CXXDestructorName: 3614 1.1 joerg case DeclarationName::CXXConversionFunctionName: 3615 1.1 joerg case DeclarationName::CXXUsingDirective: 3616 1.1 joerg return; 3617 1.1 joerg } 3618 1.1 joerg 3619 1.1 joerg llvm_unreachable("Invalid name kind?"); 3620 1.1 joerg } 3621 1.1 joerg 3622 1.1 joerg void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup, 3623 1.1 joerg unsigned DataLen) { 3624 1.1 joerg using namespace llvm::support; 3625 1.1 joerg 3626 1.1 joerg endian::Writer LE(Out, little); 3627 1.1 joerg uint64_t Start = Out.tell(); (void)Start; 3628 1.1 joerg for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) 3629 1.1 joerg LE.write<uint32_t>(DeclIDs[I]); 3630 1.1 joerg assert(Out.tell() - Start == DataLen && "Data length is wrong"); 3631 1.1 joerg } 3632 1.1 joerg }; 3633 1.1 joerg 3634 1.1 joerg } // namespace 3635 1.1 joerg 3636 1.1 joerg bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result, 3637 1.1 joerg DeclContext *DC) { 3638 1.1 joerg return Result.hasExternalDecls() && 3639 1.1 joerg DC->hasNeedToReconcileExternalVisibleStorage(); 3640 1.1 joerg } 3641 1.1 joerg 3642 1.1 joerg bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result, 3643 1.1 joerg DeclContext *DC) { 3644 1.1 joerg for (auto *D : Result.getLookupResult()) 3645 1.1 joerg if (!getDeclForLocalLookup(getLangOpts(), D)->isFromASTFile()) 3646 1.1 joerg return false; 3647 1.1 joerg 3648 1.1 joerg return true; 3649 1.1 joerg } 3650 1.1 joerg 3651 1.1 joerg void 3652 1.1 joerg ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC, 3653 1.1 joerg llvm::SmallVectorImpl<char> &LookupTable) { 3654 1.1 joerg assert(!ConstDC->hasLazyLocalLexicalLookups() && 3655 1.1 joerg !ConstDC->hasLazyExternalLexicalLookups() && 3656 1.1 joerg "must call buildLookups first"); 3657 1.1 joerg 3658 1.1 joerg // FIXME: We need to build the lookups table, which is logically const. 3659 1.1 joerg auto *DC = const_cast<DeclContext*>(ConstDC); 3660 1.1 joerg assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table"); 3661 1.1 joerg 3662 1.1 joerg // Create the on-disk hash table representation. 3663 1.1 joerg MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait, 3664 1.1 joerg ASTDeclContextNameLookupTrait> Generator; 3665 1.1 joerg ASTDeclContextNameLookupTrait Trait(*this); 3666 1.1 joerg 3667 1.1 joerg // The first step is to collect the declaration names which we need to 3668 1.1 joerg // serialize into the name lookup table, and to collect them in a stable 3669 1.1 joerg // order. 3670 1.1 joerg SmallVector<DeclarationName, 16> Names; 3671 1.1 joerg 3672 1.1 joerg // We also build up small sets of the constructor and conversion function 3673 1.1 joerg // names which are visible. 3674 1.1.1.2 joerg llvm::SmallPtrSet<DeclarationName, 8> ConstructorNameSet, ConversionNameSet; 3675 1.1 joerg 3676 1.1 joerg for (auto &Lookup : *DC->buildLookup()) { 3677 1.1 joerg auto &Name = Lookup.first; 3678 1.1 joerg auto &Result = Lookup.second; 3679 1.1 joerg 3680 1.1 joerg // If there are no local declarations in our lookup result, we 3681 1.1 joerg // don't need to write an entry for the name at all. If we can't 3682 1.1 joerg // write out a lookup set without performing more deserialization, 3683 1.1 joerg // just skip this entry. 3684 1.1 joerg if (isLookupResultExternal(Result, DC) && 3685 1.1 joerg isLookupResultEntirelyExternal(Result, DC)) 3686 1.1 joerg continue; 3687 1.1 joerg 3688 1.1 joerg // We also skip empty results. If any of the results could be external and 3689 1.1 joerg // the currently available results are empty, then all of the results are 3690 1.1 joerg // external and we skip it above. So the only way we get here with an empty 3691 1.1 joerg // results is when no results could have been external *and* we have 3692 1.1 joerg // external results. 3693 1.1 joerg // 3694 1.1 joerg // FIXME: While we might want to start emitting on-disk entries for negative 3695 1.1 joerg // lookups into a decl context as an optimization, today we *have* to skip 3696 1.1 joerg // them because there are names with empty lookup results in decl contexts 3697 1.1 joerg // which we can't emit in any stable ordering: we lookup constructors and 3698 1.1 joerg // conversion functions in the enclosing namespace scope creating empty 3699 1.1 joerg // results for them. This in almost certainly a bug in Clang's name lookup, 3700 1.1 joerg // but that is likely to be hard or impossible to fix and so we tolerate it 3701 1.1 joerg // here by omitting lookups with empty results. 3702 1.1 joerg if (Lookup.second.getLookupResult().empty()) 3703 1.1 joerg continue; 3704 1.1 joerg 3705 1.1 joerg switch (Lookup.first.getNameKind()) { 3706 1.1 joerg default: 3707 1.1 joerg Names.push_back(Lookup.first); 3708 1.1 joerg break; 3709 1.1 joerg 3710 1.1 joerg case DeclarationName::CXXConstructorName: 3711 1.1 joerg assert(isa<CXXRecordDecl>(DC) && 3712 1.1 joerg "Cannot have a constructor name outside of a class!"); 3713 1.1 joerg ConstructorNameSet.insert(Name); 3714 1.1 joerg break; 3715 1.1 joerg 3716 1.1 joerg case DeclarationName::CXXConversionFunctionName: 3717 1.1 joerg assert(isa<CXXRecordDecl>(DC) && 3718 1.1 joerg "Cannot have a conversion function name outside of a class!"); 3719 1.1 joerg ConversionNameSet.insert(Name); 3720 1.1 joerg break; 3721 1.1 joerg } 3722 1.1 joerg } 3723 1.1 joerg 3724 1.1 joerg // Sort the names into a stable order. 3725 1.1 joerg llvm::sort(Names); 3726 1.1 joerg 3727 1.1 joerg if (auto *D = dyn_cast<CXXRecordDecl>(DC)) { 3728 1.1 joerg // We need to establish an ordering of constructor and conversion function 3729 1.1 joerg // names, and they don't have an intrinsic ordering. 3730 1.1 joerg 3731 1.1 joerg // First we try the easy case by forming the current context's constructor 3732 1.1 joerg // name and adding that name first. This is a very useful optimization to 3733 1.1 joerg // avoid walking the lexical declarations in many cases, and it also 3734 1.1 joerg // handles the only case where a constructor name can come from some other 3735 1.1 joerg // lexical context -- when that name is an implicit constructor merged from 3736 1.1 joerg // another declaration in the redecl chain. Any non-implicit constructor or 3737 1.1 joerg // conversion function which doesn't occur in all the lexical contexts 3738 1.1 joerg // would be an ODR violation. 3739 1.1 joerg auto ImplicitCtorName = Context->DeclarationNames.getCXXConstructorName( 3740 1.1 joerg Context->getCanonicalType(Context->getRecordType(D))); 3741 1.1 joerg if (ConstructorNameSet.erase(ImplicitCtorName)) 3742 1.1 joerg Names.push_back(ImplicitCtorName); 3743 1.1 joerg 3744 1.1 joerg // If we still have constructors or conversion functions, we walk all the 3745 1.1 joerg // names in the decl and add the constructors and conversion functions 3746 1.1 joerg // which are visible in the order they lexically occur within the context. 3747 1.1 joerg if (!ConstructorNameSet.empty() || !ConversionNameSet.empty()) 3748 1.1 joerg for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls()) 3749 1.1 joerg if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) { 3750 1.1 joerg auto Name = ChildND->getDeclName(); 3751 1.1 joerg switch (Name.getNameKind()) { 3752 1.1 joerg default: 3753 1.1 joerg continue; 3754 1.1 joerg 3755 1.1 joerg case DeclarationName::CXXConstructorName: 3756 1.1 joerg if (ConstructorNameSet.erase(Name)) 3757 1.1 joerg Names.push_back(Name); 3758 1.1 joerg break; 3759 1.1 joerg 3760 1.1 joerg case DeclarationName::CXXConversionFunctionName: 3761 1.1 joerg if (ConversionNameSet.erase(Name)) 3762 1.1 joerg Names.push_back(Name); 3763 1.1 joerg break; 3764 1.1 joerg } 3765 1.1 joerg 3766 1.1 joerg if (ConstructorNameSet.empty() && ConversionNameSet.empty()) 3767 1.1 joerg break; 3768 1.1 joerg } 3769 1.1 joerg 3770 1.1 joerg assert(ConstructorNameSet.empty() && "Failed to find all of the visible " 3771 1.1 joerg "constructors by walking all the " 3772 1.1 joerg "lexical members of the context."); 3773 1.1 joerg assert(ConversionNameSet.empty() && "Failed to find all of the visible " 3774 1.1 joerg "conversion functions by walking all " 3775 1.1 joerg "the lexical members of the context."); 3776 1.1 joerg } 3777 1.1 joerg 3778 1.1 joerg // Next we need to do a lookup with each name into this decl context to fully 3779 1.1 joerg // populate any results from external sources. We don't actually use the 3780 1.1 joerg // results of these lookups because we only want to use the results after all 3781 1.1 joerg // results have been loaded and the pointers into them will be stable. 3782 1.1 joerg for (auto &Name : Names) 3783 1.1 joerg DC->lookup(Name); 3784 1.1 joerg 3785 1.1 joerg // Now we need to insert the results for each name into the hash table. For 3786 1.1 joerg // constructor names and conversion function names, we actually need to merge 3787 1.1 joerg // all of the results for them into one list of results each and insert 3788 1.1 joerg // those. 3789 1.1 joerg SmallVector<NamedDecl *, 8> ConstructorDecls; 3790 1.1 joerg SmallVector<NamedDecl *, 8> ConversionDecls; 3791 1.1 joerg 3792 1.1 joerg // Now loop over the names, either inserting them or appending for the two 3793 1.1 joerg // special cases. 3794 1.1 joerg for (auto &Name : Names) { 3795 1.1 joerg DeclContext::lookup_result Result = DC->noload_lookup(Name); 3796 1.1 joerg 3797 1.1 joerg switch (Name.getNameKind()) { 3798 1.1 joerg default: 3799 1.1 joerg Generator.insert(Name, Trait.getData(Result), Trait); 3800 1.1 joerg break; 3801 1.1 joerg 3802 1.1 joerg case DeclarationName::CXXConstructorName: 3803 1.1 joerg ConstructorDecls.append(Result.begin(), Result.end()); 3804 1.1 joerg break; 3805 1.1 joerg 3806 1.1 joerg case DeclarationName::CXXConversionFunctionName: 3807 1.1 joerg ConversionDecls.append(Result.begin(), Result.end()); 3808 1.1 joerg break; 3809 1.1 joerg } 3810 1.1 joerg } 3811 1.1 joerg 3812 1.1 joerg // Handle our two special cases if we ended up having any. We arbitrarily use 3813 1.1 joerg // the first declaration's name here because the name itself isn't part of 3814 1.1 joerg // the key, only the kind of name is used. 3815 1.1 joerg if (!ConstructorDecls.empty()) 3816 1.1 joerg Generator.insert(ConstructorDecls.front()->getDeclName(), 3817 1.1 joerg Trait.getData(ConstructorDecls), Trait); 3818 1.1 joerg if (!ConversionDecls.empty()) 3819 1.1 joerg Generator.insert(ConversionDecls.front()->getDeclName(), 3820 1.1 joerg Trait.getData(ConversionDecls), Trait); 3821 1.1 joerg 3822 1.1 joerg // Create the on-disk hash table. Also emit the existing imported and 3823 1.1 joerg // merged table if there is one. 3824 1.1 joerg auto *Lookups = Chain ? Chain->getLoadedLookupTables(DC) : nullptr; 3825 1.1 joerg Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table : nullptr); 3826 1.1 joerg } 3827 1.1 joerg 3828 1.1 joerg /// Write the block containing all of the declaration IDs 3829 1.1 joerg /// visible from the given DeclContext. 3830 1.1 joerg /// 3831 1.1 joerg /// \returns the offset of the DECL_CONTEXT_VISIBLE block within the 3832 1.1 joerg /// bitstream, or 0 if no block was written. 3833 1.1 joerg uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, 3834 1.1 joerg DeclContext *DC) { 3835 1.1 joerg // If we imported a key declaration of this namespace, write the visible 3836 1.1 joerg // lookup results as an update record for it rather than including them 3837 1.1 joerg // on this declaration. We will only look at key declarations on reload. 3838 1.1 joerg if (isa<NamespaceDecl>(DC) && Chain && 3839 1.1 joerg Chain->getKeyDeclaration(cast<Decl>(DC))->isFromASTFile()) { 3840 1.1 joerg // Only do this once, for the first local declaration of the namespace. 3841 1.1 joerg for (auto *Prev = cast<NamespaceDecl>(DC)->getPreviousDecl(); Prev; 3842 1.1 joerg Prev = Prev->getPreviousDecl()) 3843 1.1 joerg if (!Prev->isFromASTFile()) 3844 1.1 joerg return 0; 3845 1.1 joerg 3846 1.1 joerg // Note that we need to emit an update record for the primary context. 3847 1.1 joerg UpdatedDeclContexts.insert(DC->getPrimaryContext()); 3848 1.1 joerg 3849 1.1 joerg // Make sure all visible decls are written. They will be recorded later. We 3850 1.1 joerg // do this using a side data structure so we can sort the names into 3851 1.1 joerg // a deterministic order. 3852 1.1 joerg StoredDeclsMap *Map = DC->getPrimaryContext()->buildLookup(); 3853 1.1 joerg SmallVector<std::pair<DeclarationName, DeclContext::lookup_result>, 16> 3854 1.1 joerg LookupResults; 3855 1.1 joerg if (Map) { 3856 1.1 joerg LookupResults.reserve(Map->size()); 3857 1.1 joerg for (auto &Entry : *Map) 3858 1.1 joerg LookupResults.push_back( 3859 1.1 joerg std::make_pair(Entry.first, Entry.second.getLookupResult())); 3860 1.1 joerg } 3861 1.1 joerg 3862 1.1 joerg llvm::sort(LookupResults, llvm::less_first()); 3863 1.1 joerg for (auto &NameAndResult : LookupResults) { 3864 1.1 joerg DeclarationName Name = NameAndResult.first; 3865 1.1 joerg DeclContext::lookup_result Result = NameAndResult.second; 3866 1.1 joerg if (Name.getNameKind() == DeclarationName::CXXConstructorName || 3867 1.1 joerg Name.getNameKind() == DeclarationName::CXXConversionFunctionName) { 3868 1.1 joerg // We have to work around a name lookup bug here where negative lookup 3869 1.1 joerg // results for these names get cached in namespace lookup tables (these 3870 1.1 joerg // names should never be looked up in a namespace). 3871 1.1 joerg assert(Result.empty() && "Cannot have a constructor or conversion " 3872 1.1 joerg "function name in a namespace!"); 3873 1.1 joerg continue; 3874 1.1 joerg } 3875 1.1 joerg 3876 1.1 joerg for (NamedDecl *ND : Result) 3877 1.1 joerg if (!ND->isFromASTFile()) 3878 1.1 joerg GetDeclRef(ND); 3879 1.1 joerg } 3880 1.1 joerg 3881 1.1 joerg return 0; 3882 1.1 joerg } 3883 1.1 joerg 3884 1.1 joerg if (DC->getPrimaryContext() != DC) 3885 1.1 joerg return 0; 3886 1.1 joerg 3887 1.1 joerg // Skip contexts which don't support name lookup. 3888 1.1 joerg if (!DC->isLookupContext()) 3889 1.1 joerg return 0; 3890 1.1 joerg 3891 1.1 joerg // If not in C++, we perform name lookup for the translation unit via the 3892 1.1 joerg // IdentifierInfo chains, don't bother to build a visible-declarations table. 3893 1.1 joerg if (DC->isTranslationUnit() && !Context.getLangOpts().CPlusPlus) 3894 1.1 joerg return 0; 3895 1.1 joerg 3896 1.1 joerg // Serialize the contents of the mapping used for lookup. Note that, 3897 1.1 joerg // although we have two very different code paths, the serialized 3898 1.1 joerg // representation is the same for both cases: a declaration name, 3899 1.1 joerg // followed by a size, followed by references to the visible 3900 1.1 joerg // declarations that have that name. 3901 1.1 joerg uint64_t Offset = Stream.GetCurrentBitNo(); 3902 1.1 joerg StoredDeclsMap *Map = DC->buildLookup(); 3903 1.1 joerg if (!Map || Map->empty()) 3904 1.1 joerg return 0; 3905 1.1 joerg 3906 1.1 joerg // Create the on-disk hash table in a buffer. 3907 1.1 joerg SmallString<4096> LookupTable; 3908 1.1 joerg GenerateNameLookupTable(DC, LookupTable); 3909 1.1 joerg 3910 1.1 joerg // Write the lookup table 3911 1.1 joerg RecordData::value_type Record[] = {DECL_CONTEXT_VISIBLE}; 3912 1.1 joerg Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, 3913 1.1 joerg LookupTable); 3914 1.1 joerg ++NumVisibleDeclContexts; 3915 1.1 joerg return Offset; 3916 1.1 joerg } 3917 1.1 joerg 3918 1.1 joerg /// Write an UPDATE_VISIBLE block for the given context. 3919 1.1 joerg /// 3920 1.1 joerg /// UPDATE_VISIBLE blocks contain the declarations that are added to an existing 3921 1.1 joerg /// DeclContext in a dependent AST file. As such, they only exist for the TU 3922 1.1 joerg /// (in C++), for namespaces, and for classes with forward-declared unscoped 3923 1.1 joerg /// enumeration members (in C++11). 3924 1.1 joerg void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { 3925 1.1 joerg StoredDeclsMap *Map = DC->getLookupPtr(); 3926 1.1 joerg if (!Map || Map->empty()) 3927 1.1 joerg return; 3928 1.1 joerg 3929 1.1 joerg // Create the on-disk hash table in a buffer. 3930 1.1 joerg SmallString<4096> LookupTable; 3931 1.1 joerg GenerateNameLookupTable(DC, LookupTable); 3932 1.1 joerg 3933 1.1 joerg // If we're updating a namespace, select a key declaration as the key for the 3934 1.1 joerg // update record; those are the only ones that will be checked on reload. 3935 1.1 joerg if (isa<NamespaceDecl>(DC)) 3936 1.1 joerg DC = cast<DeclContext>(Chain->getKeyDeclaration(cast<Decl>(DC))); 3937 1.1 joerg 3938 1.1 joerg // Write the lookup table 3939 1.1 joerg RecordData::value_type Record[] = {UPDATE_VISIBLE, getDeclID(cast<Decl>(DC))}; 3940 1.1 joerg Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable); 3941 1.1 joerg } 3942 1.1 joerg 3943 1.1 joerg /// Write an FP_PRAGMA_OPTIONS block for the given FPOptions. 3944 1.1.1.2 joerg void ASTWriter::WriteFPPragmaOptions(const FPOptionsOverride &Opts) { 3945 1.1.1.2 joerg RecordData::value_type Record[] = {Opts.getAsOpaqueInt()}; 3946 1.1 joerg Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record); 3947 1.1 joerg } 3948 1.1 joerg 3949 1.1 joerg /// Write an OPENCL_EXTENSIONS block for the given OpenCLOptions. 3950 1.1 joerg void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { 3951 1.1 joerg if (!SemaRef.Context.getLangOpts().OpenCL) 3952 1.1 joerg return; 3953 1.1 joerg 3954 1.1 joerg const OpenCLOptions &Opts = SemaRef.getOpenCLOptions(); 3955 1.1 joerg RecordData Record; 3956 1.1 joerg for (const auto &I:Opts.OptMap) { 3957 1.1 joerg AddString(I.getKey(), Record); 3958 1.1 joerg auto V = I.getValue(); 3959 1.1 joerg Record.push_back(V.Supported ? 1 : 0); 3960 1.1 joerg Record.push_back(V.Enabled ? 1 : 0); 3961 1.1.1.2 joerg Record.push_back(V.WithPragma ? 1 : 0); 3962 1.1 joerg Record.push_back(V.Avail); 3963 1.1 joerg Record.push_back(V.Core); 3964 1.1.1.2 joerg Record.push_back(V.Opt); 3965 1.1 joerg } 3966 1.1 joerg Stream.EmitRecord(OPENCL_EXTENSIONS, Record); 3967 1.1 joerg } 3968 1.1 joerg void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) { 3969 1.1 joerg if (SemaRef.ForceCUDAHostDeviceDepth > 0) { 3970 1.1 joerg RecordData::value_type Record[] = {SemaRef.ForceCUDAHostDeviceDepth}; 3971 1.1 joerg Stream.EmitRecord(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH, Record); 3972 1.1 joerg } 3973 1.1 joerg } 3974 1.1 joerg 3975 1.1 joerg void ASTWriter::WriteObjCCategories() { 3976 1.1 joerg SmallVector<ObjCCategoriesInfo, 2> CategoriesMap; 3977 1.1 joerg RecordData Categories; 3978 1.1 joerg 3979 1.1 joerg for (unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) { 3980 1.1 joerg unsigned Size = 0; 3981 1.1 joerg unsigned StartIndex = Categories.size(); 3982 1.1 joerg 3983 1.1 joerg ObjCInterfaceDecl *Class = ObjCClassesWithCategories[I]; 3984 1.1 joerg 3985 1.1 joerg // Allocate space for the size. 3986 1.1 joerg Categories.push_back(0); 3987 1.1 joerg 3988 1.1 joerg // Add the categories. 3989 1.1 joerg for (ObjCInterfaceDecl::known_categories_iterator 3990 1.1 joerg Cat = Class->known_categories_begin(), 3991 1.1 joerg CatEnd = Class->known_categories_end(); 3992 1.1 joerg Cat != CatEnd; ++Cat, ++Size) { 3993 1.1 joerg assert(getDeclID(*Cat) != 0 && "Bogus category"); 3994 1.1 joerg AddDeclRef(*Cat, Categories); 3995 1.1 joerg } 3996 1.1 joerg 3997 1.1 joerg // Update the size. 3998 1.1 joerg Categories[StartIndex] = Size; 3999 1.1 joerg 4000 1.1 joerg // Record this interface -> category map. 4001 1.1 joerg ObjCCategoriesInfo CatInfo = { getDeclID(Class), StartIndex }; 4002 1.1 joerg CategoriesMap.push_back(CatInfo); 4003 1.1 joerg } 4004 1.1 joerg 4005 1.1 joerg // Sort the categories map by the definition ID, since the reader will be 4006 1.1 joerg // performing binary searches on this information. 4007 1.1 joerg llvm::array_pod_sort(CategoriesMap.begin(), CategoriesMap.end()); 4008 1.1 joerg 4009 1.1 joerg // Emit the categories map. 4010 1.1 joerg using namespace llvm; 4011 1.1 joerg 4012 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 4013 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(OBJC_CATEGORIES_MAP)); 4014 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries 4015 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 4016 1.1 joerg unsigned AbbrevID = Stream.EmitAbbrev(std::move(Abbrev)); 4017 1.1 joerg 4018 1.1 joerg RecordData::value_type Record[] = {OBJC_CATEGORIES_MAP, CategoriesMap.size()}; 4019 1.1 joerg Stream.EmitRecordWithBlob(AbbrevID, Record, 4020 1.1 joerg reinterpret_cast<char *>(CategoriesMap.data()), 4021 1.1 joerg CategoriesMap.size() * sizeof(ObjCCategoriesInfo)); 4022 1.1 joerg 4023 1.1 joerg // Emit the category lists. 4024 1.1 joerg Stream.EmitRecord(OBJC_CATEGORIES, Categories); 4025 1.1 joerg } 4026 1.1 joerg 4027 1.1 joerg void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) { 4028 1.1 joerg Sema::LateParsedTemplateMapT &LPTMap = SemaRef.LateParsedTemplateMap; 4029 1.1 joerg 4030 1.1 joerg if (LPTMap.empty()) 4031 1.1 joerg return; 4032 1.1 joerg 4033 1.1 joerg RecordData Record; 4034 1.1 joerg for (auto &LPTMapEntry : LPTMap) { 4035 1.1 joerg const FunctionDecl *FD = LPTMapEntry.first; 4036 1.1 joerg LateParsedTemplate &LPT = *LPTMapEntry.second; 4037 1.1 joerg AddDeclRef(FD, Record); 4038 1.1 joerg AddDeclRef(LPT.D, Record); 4039 1.1 joerg Record.push_back(LPT.Toks.size()); 4040 1.1 joerg 4041 1.1 joerg for (const auto &Tok : LPT.Toks) { 4042 1.1 joerg AddToken(Tok, Record); 4043 1.1 joerg } 4044 1.1 joerg } 4045 1.1 joerg Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record); 4046 1.1 joerg } 4047 1.1 joerg 4048 1.1 joerg /// Write the state of 'pragma clang optimize' at the end of the module. 4049 1.1 joerg void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) { 4050 1.1 joerg RecordData Record; 4051 1.1 joerg SourceLocation PragmaLoc = SemaRef.getOptimizeOffPragmaLocation(); 4052 1.1 joerg AddSourceLocation(PragmaLoc, Record); 4053 1.1 joerg Stream.EmitRecord(OPTIMIZE_PRAGMA_OPTIONS, Record); 4054 1.1 joerg } 4055 1.1 joerg 4056 1.1 joerg /// Write the state of 'pragma ms_struct' at the end of the module. 4057 1.1 joerg void ASTWriter::WriteMSStructPragmaOptions(Sema &SemaRef) { 4058 1.1 joerg RecordData Record; 4059 1.1 joerg Record.push_back(SemaRef.MSStructPragmaOn ? PMSST_ON : PMSST_OFF); 4060 1.1 joerg Stream.EmitRecord(MSSTRUCT_PRAGMA_OPTIONS, Record); 4061 1.1 joerg } 4062 1.1 joerg 4063 1.1 joerg /// Write the state of 'pragma pointers_to_members' at the end of the 4064 1.1 joerg //module. 4065 1.1 joerg void ASTWriter::WriteMSPointersToMembersPragmaOptions(Sema &SemaRef) { 4066 1.1 joerg RecordData Record; 4067 1.1 joerg Record.push_back(SemaRef.MSPointerToMemberRepresentationMethod); 4068 1.1 joerg AddSourceLocation(SemaRef.ImplicitMSInheritanceAttrLoc, Record); 4069 1.1 joerg Stream.EmitRecord(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS, Record); 4070 1.1 joerg } 4071 1.1 joerg 4072 1.1.1.2 joerg /// Write the state of 'pragma align/pack' at the end of the module. 4073 1.1 joerg void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) { 4074 1.1.1.2 joerg // Don't serialize pragma align/pack state for modules, since it should only 4075 1.1.1.2 joerg // take effect on a per-submodule basis. 4076 1.1.1.2 joerg if (WritingModule) 4077 1.1.1.2 joerg return; 4078 1.1.1.2 joerg 4079 1.1.1.2 joerg RecordData Record; 4080 1.1.1.2 joerg AddAlignPackInfo(SemaRef.AlignPackStack.CurrentValue, Record); 4081 1.1.1.2 joerg AddSourceLocation(SemaRef.AlignPackStack.CurrentPragmaLocation, Record); 4082 1.1.1.2 joerg Record.push_back(SemaRef.AlignPackStack.Stack.size()); 4083 1.1.1.2 joerg for (const auto &StackEntry : SemaRef.AlignPackStack.Stack) { 4084 1.1.1.2 joerg AddAlignPackInfo(StackEntry.Value, Record); 4085 1.1.1.2 joerg AddSourceLocation(StackEntry.PragmaLocation, Record); 4086 1.1.1.2 joerg AddSourceLocation(StackEntry.PragmaPushLocation, Record); 4087 1.1.1.2 joerg AddString(StackEntry.StackSlotLabel, Record); 4088 1.1.1.2 joerg } 4089 1.1.1.2 joerg Stream.EmitRecord(ALIGN_PACK_PRAGMA_OPTIONS, Record); 4090 1.1.1.2 joerg } 4091 1.1.1.2 joerg 4092 1.1.1.2 joerg /// Write the state of 'pragma float_control' at the end of the module. 4093 1.1.1.2 joerg void ASTWriter::WriteFloatControlPragmaOptions(Sema &SemaRef) { 4094 1.1.1.2 joerg // Don't serialize pragma float_control state for modules, 4095 1.1.1.2 joerg // since it should only take effect on a per-submodule basis. 4096 1.1 joerg if (WritingModule) 4097 1.1 joerg return; 4098 1.1 joerg 4099 1.1 joerg RecordData Record; 4100 1.1.1.2 joerg Record.push_back(SemaRef.FpPragmaStack.CurrentValue.getAsOpaqueInt()); 4101 1.1.1.2 joerg AddSourceLocation(SemaRef.FpPragmaStack.CurrentPragmaLocation, Record); 4102 1.1.1.2 joerg Record.push_back(SemaRef.FpPragmaStack.Stack.size()); 4103 1.1.1.2 joerg for (const auto &StackEntry : SemaRef.FpPragmaStack.Stack) { 4104 1.1.1.2 joerg Record.push_back(StackEntry.Value.getAsOpaqueInt()); 4105 1.1 joerg AddSourceLocation(StackEntry.PragmaLocation, Record); 4106 1.1 joerg AddSourceLocation(StackEntry.PragmaPushLocation, Record); 4107 1.1 joerg AddString(StackEntry.StackSlotLabel, Record); 4108 1.1 joerg } 4109 1.1.1.2 joerg Stream.EmitRecord(FLOAT_CONTROL_PRAGMA_OPTIONS, Record); 4110 1.1 joerg } 4111 1.1 joerg 4112 1.1 joerg void ASTWriter::WriteModuleFileExtension(Sema &SemaRef, 4113 1.1 joerg ModuleFileExtensionWriter &Writer) { 4114 1.1 joerg // Enter the extension block. 4115 1.1 joerg Stream.EnterSubblock(EXTENSION_BLOCK_ID, 4); 4116 1.1 joerg 4117 1.1 joerg // Emit the metadata record abbreviation. 4118 1.1 joerg auto Abv = std::make_shared<llvm::BitCodeAbbrev>(); 4119 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(EXTENSION_METADATA)); 4120 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 4121 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 4122 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 4123 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 4124 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 4125 1.1 joerg unsigned Abbrev = Stream.EmitAbbrev(std::move(Abv)); 4126 1.1 joerg 4127 1.1 joerg // Emit the metadata record. 4128 1.1 joerg RecordData Record; 4129 1.1 joerg auto Metadata = Writer.getExtension()->getExtensionMetadata(); 4130 1.1 joerg Record.push_back(EXTENSION_METADATA); 4131 1.1 joerg Record.push_back(Metadata.MajorVersion); 4132 1.1 joerg Record.push_back(Metadata.MinorVersion); 4133 1.1 joerg Record.push_back(Metadata.BlockName.size()); 4134 1.1 joerg Record.push_back(Metadata.UserInfo.size()); 4135 1.1 joerg SmallString<64> Buffer; 4136 1.1 joerg Buffer += Metadata.BlockName; 4137 1.1 joerg Buffer += Metadata.UserInfo; 4138 1.1 joerg Stream.EmitRecordWithBlob(Abbrev, Record, Buffer); 4139 1.1 joerg 4140 1.1 joerg // Emit the contents of the extension block. 4141 1.1 joerg Writer.writeExtensionContents(SemaRef, Stream); 4142 1.1 joerg 4143 1.1 joerg // Exit the extension block. 4144 1.1 joerg Stream.ExitBlock(); 4145 1.1 joerg } 4146 1.1 joerg 4147 1.1 joerg //===----------------------------------------------------------------------===// 4148 1.1 joerg // General Serialization Routines 4149 1.1 joerg //===----------------------------------------------------------------------===// 4150 1.1 joerg 4151 1.1 joerg void ASTRecordWriter::AddAttr(const Attr *A) { 4152 1.1 joerg auto &Record = *this; 4153 1.1 joerg if (!A) 4154 1.1 joerg return Record.push_back(0); 4155 1.1 joerg Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs 4156 1.1 joerg 4157 1.1 joerg Record.AddIdentifierRef(A->getAttrName()); 4158 1.1 joerg Record.AddIdentifierRef(A->getScopeName()); 4159 1.1 joerg Record.AddSourceRange(A->getRange()); 4160 1.1 joerg Record.AddSourceLocation(A->getScopeLoc()); 4161 1.1 joerg Record.push_back(A->getParsedKind()); 4162 1.1 joerg Record.push_back(A->getSyntax()); 4163 1.1 joerg Record.push_back(A->getAttributeSpellingListIndexRaw()); 4164 1.1 joerg 4165 1.1 joerg #include "clang/Serialization/AttrPCHWrite.inc" 4166 1.1 joerg } 4167 1.1 joerg 4168 1.1 joerg /// Emit the list of attributes to the specified record. 4169 1.1 joerg void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) { 4170 1.1 joerg push_back(Attrs.size()); 4171 1.1 joerg for (const auto *A : Attrs) 4172 1.1 joerg AddAttr(A); 4173 1.1 joerg } 4174 1.1 joerg 4175 1.1 joerg void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) { 4176 1.1 joerg AddSourceLocation(Tok.getLocation(), Record); 4177 1.1 joerg Record.push_back(Tok.getLength()); 4178 1.1 joerg 4179 1.1 joerg // FIXME: When reading literal tokens, reconstruct the literal pointer 4180 1.1 joerg // if it is needed. 4181 1.1 joerg AddIdentifierRef(Tok.getIdentifierInfo(), Record); 4182 1.1 joerg // FIXME: Should translate token kind to a stable encoding. 4183 1.1 joerg Record.push_back(Tok.getKind()); 4184 1.1 joerg // FIXME: Should translate token flags to a stable encoding. 4185 1.1 joerg Record.push_back(Tok.getFlags()); 4186 1.1 joerg } 4187 1.1 joerg 4188 1.1 joerg void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) { 4189 1.1 joerg Record.push_back(Str.size()); 4190 1.1 joerg Record.insert(Record.end(), Str.begin(), Str.end()); 4191 1.1 joerg } 4192 1.1 joerg 4193 1.1 joerg bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &Path) { 4194 1.1 joerg assert(Context && "should have context when outputting path"); 4195 1.1 joerg 4196 1.1 joerg bool Changed = 4197 1.1 joerg cleanPathForOutput(Context->getSourceManager().getFileManager(), Path); 4198 1.1 joerg 4199 1.1 joerg // Remove a prefix to make the path relative, if relevant. 4200 1.1 joerg const char *PathBegin = Path.data(); 4201 1.1 joerg const char *PathPtr = 4202 1.1 joerg adjustFilenameForRelocatableAST(PathBegin, BaseDirectory); 4203 1.1 joerg if (PathPtr != PathBegin) { 4204 1.1 joerg Path.erase(Path.begin(), Path.begin() + (PathPtr - PathBegin)); 4205 1.1 joerg Changed = true; 4206 1.1 joerg } 4207 1.1 joerg 4208 1.1 joerg return Changed; 4209 1.1 joerg } 4210 1.1 joerg 4211 1.1 joerg void ASTWriter::AddPath(StringRef Path, RecordDataImpl &Record) { 4212 1.1 joerg SmallString<128> FilePath(Path); 4213 1.1 joerg PreparePathForOutput(FilePath); 4214 1.1 joerg AddString(FilePath, Record); 4215 1.1 joerg } 4216 1.1 joerg 4217 1.1 joerg void ASTWriter::EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record, 4218 1.1 joerg StringRef Path) { 4219 1.1 joerg SmallString<128> FilePath(Path); 4220 1.1 joerg PreparePathForOutput(FilePath); 4221 1.1 joerg Stream.EmitRecordWithBlob(Abbrev, Record, FilePath); 4222 1.1 joerg } 4223 1.1 joerg 4224 1.1 joerg void ASTWriter::AddVersionTuple(const VersionTuple &Version, 4225 1.1 joerg RecordDataImpl &Record) { 4226 1.1 joerg Record.push_back(Version.getMajor()); 4227 1.1 joerg if (Optional<unsigned> Minor = Version.getMinor()) 4228 1.1 joerg Record.push_back(*Minor + 1); 4229 1.1 joerg else 4230 1.1 joerg Record.push_back(0); 4231 1.1 joerg if (Optional<unsigned> Subminor = Version.getSubminor()) 4232 1.1 joerg Record.push_back(*Subminor + 1); 4233 1.1 joerg else 4234 1.1 joerg Record.push_back(0); 4235 1.1 joerg } 4236 1.1 joerg 4237 1.1 joerg /// Note that the identifier II occurs at the given offset 4238 1.1 joerg /// within the identifier table. 4239 1.1 joerg void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { 4240 1.1 joerg IdentID ID = IdentifierIDs[II]; 4241 1.1 joerg // Only store offsets new to this AST file. Other identifier names are looked 4242 1.1 joerg // up earlier in the chain and thus don't need an offset. 4243 1.1 joerg if (ID >= FirstIdentID) 4244 1.1 joerg IdentifierOffsets[ID - FirstIdentID] = Offset; 4245 1.1 joerg } 4246 1.1 joerg 4247 1.1 joerg /// Note that the selector Sel occurs at the given offset 4248 1.1 joerg /// within the method pool/selector table. 4249 1.1 joerg void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { 4250 1.1 joerg unsigned ID = SelectorIDs[Sel]; 4251 1.1 joerg assert(ID && "Unknown selector"); 4252 1.1 joerg // Don't record offsets for selectors that are also available in a different 4253 1.1 joerg // file. 4254 1.1 joerg if (ID < FirstSelectorID) 4255 1.1 joerg return; 4256 1.1 joerg SelectorOffsets[ID - FirstSelectorID] = Offset; 4257 1.1 joerg } 4258 1.1 joerg 4259 1.1 joerg ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream, 4260 1.1 joerg SmallVectorImpl<char> &Buffer, 4261 1.1 joerg InMemoryModuleCache &ModuleCache, 4262 1.1 joerg ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, 4263 1.1 joerg bool IncludeTimestamps) 4264 1.1 joerg : Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache), 4265 1.1 joerg IncludeTimestamps(IncludeTimestamps) { 4266 1.1 joerg for (const auto &Ext : Extensions) { 4267 1.1 joerg if (auto Writer = Ext->createExtensionWriter(*this)) 4268 1.1 joerg ModuleFileExtensionWriters.push_back(std::move(Writer)); 4269 1.1 joerg } 4270 1.1 joerg } 4271 1.1 joerg 4272 1.1.1.2 joerg ASTWriter::~ASTWriter() = default; 4273 1.1 joerg 4274 1.1 joerg const LangOptions &ASTWriter::getLangOpts() const { 4275 1.1 joerg assert(WritingAST && "can't determine lang opts when not writing AST"); 4276 1.1 joerg return Context->getLangOpts(); 4277 1.1 joerg } 4278 1.1 joerg 4279 1.1 joerg time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const { 4280 1.1 joerg return IncludeTimestamps ? E->getModificationTime() : 0; 4281 1.1 joerg } 4282 1.1 joerg 4283 1.1 joerg ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, 4284 1.1 joerg const std::string &OutputFile, 4285 1.1 joerg Module *WritingModule, StringRef isysroot, 4286 1.1 joerg bool hasErrors, 4287 1.1 joerg bool ShouldCacheASTInMemory) { 4288 1.1 joerg WritingAST = true; 4289 1.1 joerg 4290 1.1 joerg ASTHasCompilerErrors = hasErrors; 4291 1.1 joerg 4292 1.1 joerg // Emit the file header. 4293 1.1 joerg Stream.Emit((unsigned)'C', 8); 4294 1.1 joerg Stream.Emit((unsigned)'P', 8); 4295 1.1 joerg Stream.Emit((unsigned)'C', 8); 4296 1.1 joerg Stream.Emit((unsigned)'H', 8); 4297 1.1 joerg 4298 1.1 joerg WriteBlockInfoBlock(); 4299 1.1 joerg 4300 1.1 joerg Context = &SemaRef.Context; 4301 1.1 joerg PP = &SemaRef.PP; 4302 1.1 joerg this->WritingModule = WritingModule; 4303 1.1 joerg ASTFileSignature Signature = 4304 1.1 joerg WriteASTCore(SemaRef, isysroot, OutputFile, WritingModule); 4305 1.1 joerg Context = nullptr; 4306 1.1 joerg PP = nullptr; 4307 1.1 joerg this->WritingModule = nullptr; 4308 1.1 joerg this->BaseDirectory.clear(); 4309 1.1 joerg 4310 1.1 joerg WritingAST = false; 4311 1.1 joerg if (ShouldCacheASTInMemory) { 4312 1.1 joerg // Construct MemoryBuffer and update buffer manager. 4313 1.1 joerg ModuleCache.addBuiltPCM(OutputFile, 4314 1.1 joerg llvm::MemoryBuffer::getMemBufferCopy( 4315 1.1 joerg StringRef(Buffer.begin(), Buffer.size()))); 4316 1.1 joerg } 4317 1.1 joerg return Signature; 4318 1.1 joerg } 4319 1.1 joerg 4320 1.1 joerg template<typename Vector> 4321 1.1 joerg static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec, 4322 1.1 joerg ASTWriter::RecordData &Record) { 4323 1.1 joerg for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end(); 4324 1.1 joerg I != E; ++I) { 4325 1.1 joerg Writer.AddDeclRef(*I, Record); 4326 1.1 joerg } 4327 1.1 joerg } 4328 1.1 joerg 4329 1.1 joerg ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, 4330 1.1 joerg const std::string &OutputFile, 4331 1.1 joerg Module *WritingModule) { 4332 1.1 joerg using namespace llvm; 4333 1.1 joerg 4334 1.1 joerg bool isModule = WritingModule != nullptr; 4335 1.1 joerg 4336 1.1 joerg // Make sure that the AST reader knows to finalize itself. 4337 1.1 joerg if (Chain) 4338 1.1 joerg Chain->finalizeForWriting(); 4339 1.1 joerg 4340 1.1 joerg ASTContext &Context = SemaRef.Context; 4341 1.1 joerg Preprocessor &PP = SemaRef.PP; 4342 1.1 joerg 4343 1.1 joerg // Set up predefined declaration IDs. 4344 1.1 joerg auto RegisterPredefDecl = [&] (Decl *D, PredefinedDeclIDs ID) { 4345 1.1 joerg if (D) { 4346 1.1 joerg assert(D->isCanonicalDecl() && "predefined decl is not canonical"); 4347 1.1 joerg DeclIDs[D] = ID; 4348 1.1 joerg } 4349 1.1 joerg }; 4350 1.1 joerg RegisterPredefDecl(Context.getTranslationUnitDecl(), 4351 1.1 joerg PREDEF_DECL_TRANSLATION_UNIT_ID); 4352 1.1 joerg RegisterPredefDecl(Context.ObjCIdDecl, PREDEF_DECL_OBJC_ID_ID); 4353 1.1 joerg RegisterPredefDecl(Context.ObjCSelDecl, PREDEF_DECL_OBJC_SEL_ID); 4354 1.1 joerg RegisterPredefDecl(Context.ObjCClassDecl, PREDEF_DECL_OBJC_CLASS_ID); 4355 1.1 joerg RegisterPredefDecl(Context.ObjCProtocolClassDecl, 4356 1.1 joerg PREDEF_DECL_OBJC_PROTOCOL_ID); 4357 1.1 joerg RegisterPredefDecl(Context.Int128Decl, PREDEF_DECL_INT_128_ID); 4358 1.1 joerg RegisterPredefDecl(Context.UInt128Decl, PREDEF_DECL_UNSIGNED_INT_128_ID); 4359 1.1 joerg RegisterPredefDecl(Context.ObjCInstanceTypeDecl, 4360 1.1 joerg PREDEF_DECL_OBJC_INSTANCETYPE_ID); 4361 1.1 joerg RegisterPredefDecl(Context.BuiltinVaListDecl, PREDEF_DECL_BUILTIN_VA_LIST_ID); 4362 1.1 joerg RegisterPredefDecl(Context.VaListTagDecl, PREDEF_DECL_VA_LIST_TAG); 4363 1.1 joerg RegisterPredefDecl(Context.BuiltinMSVaListDecl, 4364 1.1 joerg PREDEF_DECL_BUILTIN_MS_VA_LIST_ID); 4365 1.1.1.2 joerg RegisterPredefDecl(Context.MSGuidTagDecl, 4366 1.1.1.2 joerg PREDEF_DECL_BUILTIN_MS_GUID_ID); 4367 1.1 joerg RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID); 4368 1.1 joerg RegisterPredefDecl(Context.MakeIntegerSeqDecl, 4369 1.1 joerg PREDEF_DECL_MAKE_INTEGER_SEQ_ID); 4370 1.1 joerg RegisterPredefDecl(Context.CFConstantStringTypeDecl, 4371 1.1 joerg PREDEF_DECL_CF_CONSTANT_STRING_ID); 4372 1.1 joerg RegisterPredefDecl(Context.CFConstantStringTagDecl, 4373 1.1 joerg PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID); 4374 1.1 joerg RegisterPredefDecl(Context.TypePackElementDecl, 4375 1.1 joerg PREDEF_DECL_TYPE_PACK_ELEMENT_ID); 4376 1.1 joerg 4377 1.1 joerg // Build a record containing all of the tentative definitions in this file, in 4378 1.1 joerg // TentativeDefinitions order. Generally, this record will be empty for 4379 1.1 joerg // headers. 4380 1.1 joerg RecordData TentativeDefinitions; 4381 1.1 joerg AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions); 4382 1.1 joerg 4383 1.1 joerg // Build a record containing all of the file scoped decls in this file. 4384 1.1 joerg RecordData UnusedFileScopedDecls; 4385 1.1 joerg if (!isModule) 4386 1.1 joerg AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls, 4387 1.1 joerg UnusedFileScopedDecls); 4388 1.1 joerg 4389 1.1 joerg // Build a record containing all of the delegating constructors we still need 4390 1.1 joerg // to resolve. 4391 1.1 joerg RecordData DelegatingCtorDecls; 4392 1.1 joerg if (!isModule) 4393 1.1 joerg AddLazyVectorDecls(*this, SemaRef.DelegatingCtorDecls, DelegatingCtorDecls); 4394 1.1 joerg 4395 1.1 joerg // Write the set of weak, undeclared identifiers. We always write the 4396 1.1 joerg // entire table, since later PCH files in a PCH chain are only interested in 4397 1.1 joerg // the results at the end of the chain. 4398 1.1 joerg RecordData WeakUndeclaredIdentifiers; 4399 1.1 joerg for (auto &WeakUndeclaredIdentifier : SemaRef.WeakUndeclaredIdentifiers) { 4400 1.1 joerg IdentifierInfo *II = WeakUndeclaredIdentifier.first; 4401 1.1 joerg WeakInfo &WI = WeakUndeclaredIdentifier.second; 4402 1.1 joerg AddIdentifierRef(II, WeakUndeclaredIdentifiers); 4403 1.1 joerg AddIdentifierRef(WI.getAlias(), WeakUndeclaredIdentifiers); 4404 1.1 joerg AddSourceLocation(WI.getLocation(), WeakUndeclaredIdentifiers); 4405 1.1 joerg WeakUndeclaredIdentifiers.push_back(WI.getUsed()); 4406 1.1 joerg } 4407 1.1 joerg 4408 1.1 joerg // Build a record containing all of the ext_vector declarations. 4409 1.1 joerg RecordData ExtVectorDecls; 4410 1.1 joerg AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls); 4411 1.1 joerg 4412 1.1 joerg // Build a record containing all of the VTable uses information. 4413 1.1 joerg RecordData VTableUses; 4414 1.1 joerg if (!SemaRef.VTableUses.empty()) { 4415 1.1 joerg for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { 4416 1.1 joerg AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); 4417 1.1 joerg AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); 4418 1.1 joerg VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); 4419 1.1 joerg } 4420 1.1 joerg } 4421 1.1 joerg 4422 1.1 joerg // Build a record containing all of the UnusedLocalTypedefNameCandidates. 4423 1.1 joerg RecordData UnusedLocalTypedefNameCandidates; 4424 1.1 joerg for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates) 4425 1.1 joerg AddDeclRef(TD, UnusedLocalTypedefNameCandidates); 4426 1.1 joerg 4427 1.1 joerg // Build a record containing all of pending implicit instantiations. 4428 1.1 joerg RecordData PendingInstantiations; 4429 1.1 joerg for (const auto &I : SemaRef.PendingInstantiations) { 4430 1.1 joerg AddDeclRef(I.first, PendingInstantiations); 4431 1.1 joerg AddSourceLocation(I.second, PendingInstantiations); 4432 1.1 joerg } 4433 1.1 joerg assert(SemaRef.PendingLocalImplicitInstantiations.empty() && 4434 1.1 joerg "There are local ones at end of translation unit!"); 4435 1.1 joerg 4436 1.1 joerg // Build a record containing some declaration references. 4437 1.1 joerg RecordData SemaDeclRefs; 4438 1.1 joerg if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) { 4439 1.1 joerg AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); 4440 1.1 joerg AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); 4441 1.1 joerg AddDeclRef(SemaRef.getStdAlignValT(), SemaDeclRefs); 4442 1.1 joerg } 4443 1.1 joerg 4444 1.1 joerg RecordData CUDASpecialDeclRefs; 4445 1.1 joerg if (Context.getcudaConfigureCallDecl()) { 4446 1.1 joerg AddDeclRef(Context.getcudaConfigureCallDecl(), CUDASpecialDeclRefs); 4447 1.1 joerg } 4448 1.1 joerg 4449 1.1 joerg // Build a record containing all of the known namespaces. 4450 1.1 joerg RecordData KnownNamespaces; 4451 1.1 joerg for (const auto &I : SemaRef.KnownNamespaces) { 4452 1.1 joerg if (!I.second) 4453 1.1 joerg AddDeclRef(I.first, KnownNamespaces); 4454 1.1 joerg } 4455 1.1 joerg 4456 1.1 joerg // Build a record of all used, undefined objects that require definitions. 4457 1.1 joerg RecordData UndefinedButUsed; 4458 1.1 joerg 4459 1.1 joerg SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined; 4460 1.1 joerg SemaRef.getUndefinedButUsed(Undefined); 4461 1.1 joerg for (const auto &I : Undefined) { 4462 1.1 joerg AddDeclRef(I.first, UndefinedButUsed); 4463 1.1 joerg AddSourceLocation(I.second, UndefinedButUsed); 4464 1.1 joerg } 4465 1.1 joerg 4466 1.1 joerg // Build a record containing all delete-expressions that we would like to 4467 1.1 joerg // analyze later in AST. 4468 1.1 joerg RecordData DeleteExprsToAnalyze; 4469 1.1 joerg 4470 1.1 joerg if (!isModule) { 4471 1.1 joerg for (const auto &DeleteExprsInfo : 4472 1.1 joerg SemaRef.getMismatchingDeleteExpressions()) { 4473 1.1 joerg AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze); 4474 1.1 joerg DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size()); 4475 1.1 joerg for (const auto &DeleteLoc : DeleteExprsInfo.second) { 4476 1.1 joerg AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze); 4477 1.1 joerg DeleteExprsToAnalyze.push_back(DeleteLoc.second); 4478 1.1 joerg } 4479 1.1 joerg } 4480 1.1 joerg } 4481 1.1 joerg 4482 1.1 joerg // Write the control block 4483 1.1 joerg WriteControlBlock(PP, Context, isysroot, OutputFile); 4484 1.1 joerg 4485 1.1 joerg // Write the remaining AST contents. 4486 1.1.1.2 joerg Stream.FlushToWord(); 4487 1.1.1.2 joerg ASTBlockRange.first = Stream.GetCurrentBitNo(); 4488 1.1 joerg Stream.EnterSubblock(AST_BLOCK_ID, 5); 4489 1.1.1.2 joerg ASTBlockStartOffset = Stream.GetCurrentBitNo(); 4490 1.1 joerg 4491 1.1 joerg // This is so that older clang versions, before the introduction 4492 1.1 joerg // of the control block, can read and reject the newer PCH format. 4493 1.1 joerg { 4494 1.1 joerg RecordData Record = {VERSION_MAJOR}; 4495 1.1 joerg Stream.EmitRecord(METADATA_OLD_FORMAT, Record); 4496 1.1 joerg } 4497 1.1 joerg 4498 1.1 joerg // Create a lexical update block containing all of the declarations in the 4499 1.1 joerg // translation unit that do not come from other AST files. 4500 1.1 joerg const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); 4501 1.1 joerg SmallVector<uint32_t, 128> NewGlobalKindDeclPairs; 4502 1.1 joerg for (const auto *D : TU->noload_decls()) { 4503 1.1 joerg if (!D->isFromASTFile()) { 4504 1.1 joerg NewGlobalKindDeclPairs.push_back(D->getKind()); 4505 1.1 joerg NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); 4506 1.1 joerg } 4507 1.1 joerg } 4508 1.1 joerg 4509 1.1 joerg auto Abv = std::make_shared<BitCodeAbbrev>(); 4510 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); 4511 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 4512 1.1 joerg unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv)); 4513 1.1 joerg { 4514 1.1 joerg RecordData::value_type Record[] = {TU_UPDATE_LEXICAL}; 4515 1.1 joerg Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, 4516 1.1 joerg bytes(NewGlobalKindDeclPairs)); 4517 1.1 joerg } 4518 1.1 joerg 4519 1.1 joerg // And a visible updates block for the translation unit. 4520 1.1 joerg Abv = std::make_shared<BitCodeAbbrev>(); 4521 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); 4522 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); 4523 1.1 joerg Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); 4524 1.1 joerg UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv)); 4525 1.1 joerg WriteDeclContextVisibleUpdate(TU); 4526 1.1 joerg 4527 1.1 joerg // If we have any extern "C" names, write out a visible update for them. 4528 1.1 joerg if (Context.ExternCContext) 4529 1.1 joerg WriteDeclContextVisibleUpdate(Context.ExternCContext); 4530 1.1 joerg 4531 1.1 joerg // If the translation unit has an anonymous namespace, and we don't already 4532 1.1 joerg // have an update block for it, write it as an update block. 4533 1.1 joerg // FIXME: Why do we not do this if there's already an update block? 4534 1.1 joerg if (NamespaceDecl *NS = TU->getAnonymousNamespace()) { 4535 1.1 joerg ASTWriter::UpdateRecord &Record = DeclUpdates[TU]; 4536 1.1 joerg if (Record.empty()) 4537 1.1 joerg Record.push_back(DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, NS)); 4538 1.1 joerg } 4539 1.1 joerg 4540 1.1 joerg // Add update records for all mangling numbers and static local numbers. 4541 1.1 joerg // These aren't really update records, but this is a convenient way of 4542 1.1 joerg // tagging this rare extra data onto the declarations. 4543 1.1 joerg for (const auto &Number : Context.MangleNumbers) 4544 1.1 joerg if (!Number.first->isFromASTFile()) 4545 1.1 joerg DeclUpdates[Number.first].push_back(DeclUpdate(UPD_MANGLING_NUMBER, 4546 1.1 joerg Number.second)); 4547 1.1 joerg for (const auto &Number : Context.StaticLocalNumbers) 4548 1.1 joerg if (!Number.first->isFromASTFile()) 4549 1.1 joerg DeclUpdates[Number.first].push_back(DeclUpdate(UPD_STATIC_LOCAL_NUMBER, 4550 1.1 joerg Number.second)); 4551 1.1 joerg 4552 1.1 joerg // Make sure visible decls, added to DeclContexts previously loaded from 4553 1.1 joerg // an AST file, are registered for serialization. Likewise for template 4554 1.1 joerg // specializations added to imported templates. 4555 1.1 joerg for (const auto *I : DeclsToEmitEvenIfUnreferenced) { 4556 1.1 joerg GetDeclRef(I); 4557 1.1 joerg } 4558 1.1 joerg 4559 1.1 joerg // Make sure all decls associated with an identifier are registered for 4560 1.1 joerg // serialization, if we're storing decls with identifiers. 4561 1.1 joerg if (!WritingModule || !getLangOpts().CPlusPlus) { 4562 1.1 joerg llvm::SmallVector<const IdentifierInfo*, 256> IIs; 4563 1.1 joerg for (const auto &ID : PP.getIdentifierTable()) { 4564 1.1 joerg const IdentifierInfo *II = ID.second; 4565 1.1 joerg if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) 4566 1.1 joerg IIs.push_back(II); 4567 1.1 joerg } 4568 1.1 joerg // Sort the identifiers to visit based on their name. 4569 1.1 joerg llvm::sort(IIs, llvm::deref<std::less<>>()); 4570 1.1 joerg for (const IdentifierInfo *II : IIs) { 4571 1.1 joerg for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), 4572 1.1 joerg DEnd = SemaRef.IdResolver.end(); 4573 1.1 joerg D != DEnd; ++D) { 4574 1.1 joerg GetDeclRef(*D); 4575 1.1 joerg } 4576 1.1 joerg } 4577 1.1 joerg } 4578 1.1 joerg 4579 1.1 joerg // For method pool in the module, if it contains an entry for a selector, 4580 1.1 joerg // the entry should be complete, containing everything introduced by that 4581 1.1 joerg // module and all modules it imports. It's possible that the entry is out of 4582 1.1 joerg // date, so we need to pull in the new content here. 4583 1.1 joerg 4584 1.1 joerg // It's possible that updateOutOfDateSelector can update SelectorIDs. To be 4585 1.1 joerg // safe, we copy all selectors out. 4586 1.1 joerg llvm::SmallVector<Selector, 256> AllSelectors; 4587 1.1 joerg for (auto &SelectorAndID : SelectorIDs) 4588 1.1 joerg AllSelectors.push_back(SelectorAndID.first); 4589 1.1 joerg for (auto &Selector : AllSelectors) 4590 1.1 joerg SemaRef.updateOutOfDateSelector(Selector); 4591 1.1 joerg 4592 1.1 joerg // Form the record of special types. 4593 1.1 joerg RecordData SpecialTypes; 4594 1.1 joerg AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes); 4595 1.1 joerg AddTypeRef(Context.getFILEType(), SpecialTypes); 4596 1.1 joerg AddTypeRef(Context.getjmp_bufType(), SpecialTypes); 4597 1.1 joerg AddTypeRef(Context.getsigjmp_bufType(), SpecialTypes); 4598 1.1 joerg AddTypeRef(Context.ObjCIdRedefinitionType, SpecialTypes); 4599 1.1 joerg AddTypeRef(Context.ObjCClassRedefinitionType, SpecialTypes); 4600 1.1 joerg AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes); 4601 1.1 joerg AddTypeRef(Context.getucontext_tType(), SpecialTypes); 4602 1.1 joerg 4603 1.1 joerg if (Chain) { 4604 1.1 joerg // Write the mapping information describing our module dependencies and how 4605 1.1 joerg // each of those modules were mapped into our own offset/ID space, so that 4606 1.1 joerg // the reader can build the appropriate mapping to its own offset/ID space. 4607 1.1 joerg // The map consists solely of a blob with the following format: 4608 1.1 joerg // *(module-kind:i8 4609 1.1 joerg // module-name-len:i16 module-name:len*i8 4610 1.1 joerg // source-location-offset:i32 4611 1.1 joerg // identifier-id:i32 4612 1.1 joerg // preprocessed-entity-id:i32 4613 1.1 joerg // macro-definition-id:i32 4614 1.1 joerg // submodule-id:i32 4615 1.1 joerg // selector-id:i32 4616 1.1 joerg // declaration-id:i32 4617 1.1 joerg // c++-base-specifiers-id:i32 4618 1.1 joerg // type-id:i32) 4619 1.1 joerg // 4620 1.1.1.2 joerg // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule, 4621 1.1.1.2 joerg // MK_ExplicitModule or MK_ImplicitModule, then the module-name is the 4622 1.1.1.2 joerg // module name. Otherwise, it is the module file name. 4623 1.1 joerg auto Abbrev = std::make_shared<BitCodeAbbrev>(); 4624 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP)); 4625 1.1 joerg Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 4626 1.1 joerg unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); 4627 1.1 joerg SmallString<2048> Buffer; 4628 1.1 joerg { 4629 1.1 joerg llvm::raw_svector_ostream Out(Buffer); 4630 1.1 joerg for (ModuleFile &M : Chain->ModuleMgr) { 4631 1.1 joerg using namespace llvm::support; 4632 1.1 joerg 4633 1.1 joerg endian::Writer LE(Out, little); 4634 1.1 joerg LE.write<uint8_t>(static_cast<uint8_t>(M.Kind)); 4635 1.1.1.2 joerg StringRef Name = M.isModule() ? M.ModuleName : M.FileName; 4636 1.1 joerg LE.write<uint16_t>(Name.size()); 4637 1.1 joerg Out.write(Name.data(), Name.size()); 4638 1.1 joerg 4639 1.1 joerg // Note: if a base ID was uint max, it would not be possible to load 4640 1.1 joerg // another module after it or have more than one entity inside it. 4641 1.1 joerg uint32_t None = std::numeric_limits<uint32_t>::max(); 4642 1.1 joerg 4643 1.1 joerg auto writeBaseIDOrNone = [&](uint32_t BaseID, bool ShouldWrite) { 4644 1.1 joerg assert(BaseID < std::numeric_limits<uint32_t>::max() && "base id too high"); 4645 1.1 joerg if (ShouldWrite) 4646 1.1 joerg LE.write<uint32_t>(BaseID); 4647 1.1 joerg else 4648 1.1 joerg LE.write<uint32_t>(None); 4649 1.1 joerg }; 4650 1.1 joerg 4651 1.1 joerg // These values should be unique within a chain, since they will be read 4652 1.1 joerg // as keys into ContinuousRangeMaps. 4653 1.1 joerg writeBaseIDOrNone(M.SLocEntryBaseOffset, M.LocalNumSLocEntries); 4654 1.1 joerg writeBaseIDOrNone(M.BaseIdentifierID, M.LocalNumIdentifiers); 4655 1.1 joerg writeBaseIDOrNone(M.BaseMacroID, M.LocalNumMacros); 4656 1.1 joerg writeBaseIDOrNone(M.BasePreprocessedEntityID, 4657 1.1 joerg M.NumPreprocessedEntities); 4658 1.1 joerg writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules); 4659 1.1 joerg writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors); 4660 1.1 joerg writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls); 4661 1.1 joerg writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes); 4662 1.1 joerg } 4663 1.1 joerg } 4664 1.1 joerg RecordData::value_type Record[] = {MODULE_OFFSET_MAP}; 4665 1.1 joerg Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record, 4666 1.1 joerg Buffer.data(), Buffer.size()); 4667 1.1 joerg } 4668 1.1 joerg 4669 1.1.1.2 joerg // Build a record containing all of the DeclsToCheckForDeferredDiags. 4670 1.1.1.2 joerg SmallVector<serialization::DeclID, 64> DeclsToCheckForDeferredDiags; 4671 1.1.1.2 joerg for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) 4672 1.1.1.2 joerg DeclsToCheckForDeferredDiags.push_back(GetDeclRef(D)); 4673 1.1.1.2 joerg 4674 1.1 joerg RecordData DeclUpdatesOffsetsRecord; 4675 1.1 joerg 4676 1.1 joerg // Keep writing types, declarations, and declaration update records 4677 1.1 joerg // until we've emitted all of them. 4678 1.1 joerg Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5); 4679 1.1.1.2 joerg DeclTypesBlockStartOffset = Stream.GetCurrentBitNo(); 4680 1.1 joerg WriteTypeAbbrevs(); 4681 1.1 joerg WriteDeclAbbrevs(); 4682 1.1 joerg do { 4683 1.1 joerg WriteDeclUpdatesBlocks(DeclUpdatesOffsetsRecord); 4684 1.1 joerg while (!DeclTypesToEmit.empty()) { 4685 1.1 joerg DeclOrType DOT = DeclTypesToEmit.front(); 4686 1.1 joerg DeclTypesToEmit.pop(); 4687 1.1 joerg if (DOT.isType()) 4688 1.1 joerg WriteType(DOT.getType()); 4689 1.1 joerg else 4690 1.1 joerg WriteDecl(Context, DOT.getDecl()); 4691 1.1 joerg } 4692 1.1 joerg } while (!DeclUpdates.empty()); 4693 1.1 joerg Stream.ExitBlock(); 4694 1.1 joerg 4695 1.1 joerg DoneWritingDeclsAndTypes = true; 4696 1.1 joerg 4697 1.1 joerg // These things can only be done once we've written out decls and types. 4698 1.1 joerg WriteTypeDeclOffsets(); 4699 1.1 joerg if (!DeclUpdatesOffsetsRecord.empty()) 4700 1.1 joerg Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord); 4701 1.1 joerg WriteFileDeclIDsMap(); 4702 1.1 joerg WriteSourceManagerBlock(Context.getSourceManager(), PP); 4703 1.1 joerg WriteComments(); 4704 1.1 joerg WritePreprocessor(PP, isModule); 4705 1.1 joerg WriteHeaderSearch(PP.getHeaderSearchInfo()); 4706 1.1 joerg WriteSelectors(SemaRef); 4707 1.1 joerg WriteReferencedSelectorsPool(SemaRef); 4708 1.1 joerg WriteLateParsedTemplates(SemaRef); 4709 1.1 joerg WriteIdentifierTable(PP, SemaRef.IdResolver, isModule); 4710 1.1.1.2 joerg WriteFPPragmaOptions(SemaRef.CurFPFeatureOverrides()); 4711 1.1 joerg WriteOpenCLExtensions(SemaRef); 4712 1.1 joerg WriteCUDAPragmas(SemaRef); 4713 1.1 joerg 4714 1.1 joerg // If we're emitting a module, write out the submodule information. 4715 1.1 joerg if (WritingModule) 4716 1.1 joerg WriteSubmodules(WritingModule); 4717 1.1 joerg 4718 1.1 joerg Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes); 4719 1.1 joerg 4720 1.1 joerg // Write the record containing external, unnamed definitions. 4721 1.1 joerg if (!EagerlyDeserializedDecls.empty()) 4722 1.1 joerg Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls); 4723 1.1 joerg 4724 1.1 joerg if (!ModularCodegenDecls.empty()) 4725 1.1 joerg Stream.EmitRecord(MODULAR_CODEGEN_DECLS, ModularCodegenDecls); 4726 1.1 joerg 4727 1.1 joerg // Write the record containing tentative definitions. 4728 1.1 joerg if (!TentativeDefinitions.empty()) 4729 1.1 joerg Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions); 4730 1.1 joerg 4731 1.1 joerg // Write the record containing unused file scoped decls. 4732 1.1 joerg if (!UnusedFileScopedDecls.empty()) 4733 1.1 joerg Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); 4734 1.1 joerg 4735 1.1 joerg // Write the record containing weak undeclared identifiers. 4736 1.1 joerg if (!WeakUndeclaredIdentifiers.empty()) 4737 1.1 joerg Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, 4738 1.1 joerg WeakUndeclaredIdentifiers); 4739 1.1 joerg 4740 1.1 joerg // Write the record containing ext_vector type names. 4741 1.1 joerg if (!ExtVectorDecls.empty()) 4742 1.1 joerg Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); 4743 1.1 joerg 4744 1.1 joerg // Write the record containing VTable uses information. 4745 1.1 joerg if (!VTableUses.empty()) 4746 1.1 joerg Stream.EmitRecord(VTABLE_USES, VTableUses); 4747 1.1 joerg 4748 1.1 joerg // Write the record containing potentially unused local typedefs. 4749 1.1 joerg if (!UnusedLocalTypedefNameCandidates.empty()) 4750 1.1 joerg Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES, 4751 1.1 joerg UnusedLocalTypedefNameCandidates); 4752 1.1 joerg 4753 1.1 joerg // Write the record containing pending implicit instantiations. 4754 1.1 joerg if (!PendingInstantiations.empty()) 4755 1.1 joerg Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); 4756 1.1 joerg 4757 1.1 joerg // Write the record containing declaration references of Sema. 4758 1.1 joerg if (!SemaDeclRefs.empty()) 4759 1.1 joerg Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); 4760 1.1 joerg 4761 1.1.1.2 joerg // Write the record containing decls to be checked for deferred diags. 4762 1.1.1.2 joerg if (!DeclsToCheckForDeferredDiags.empty()) 4763 1.1.1.2 joerg Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS, 4764 1.1.1.2 joerg DeclsToCheckForDeferredDiags); 4765 1.1.1.2 joerg 4766 1.1 joerg // Write the record containing CUDA-specific declaration references. 4767 1.1 joerg if (!CUDASpecialDeclRefs.empty()) 4768 1.1 joerg Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs); 4769 1.1 joerg 4770 1.1 joerg // Write the delegating constructors. 4771 1.1 joerg if (!DelegatingCtorDecls.empty()) 4772 1.1 joerg Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls); 4773 1.1 joerg 4774 1.1 joerg // Write the known namespaces. 4775 1.1 joerg if (!KnownNamespaces.empty()) 4776 1.1 joerg Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces); 4777 1.1 joerg 4778 1.1 joerg // Write the undefined internal functions and variables, and inline functions. 4779 1.1 joerg if (!UndefinedButUsed.empty()) 4780 1.1 joerg Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed); 4781 1.1 joerg 4782 1.1 joerg if (!DeleteExprsToAnalyze.empty()) 4783 1.1 joerg Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze); 4784 1.1 joerg 4785 1.1 joerg // Write the visible updates to DeclContexts. 4786 1.1 joerg for (auto *DC : UpdatedDeclContexts) 4787 1.1 joerg WriteDeclContextVisibleUpdate(DC); 4788 1.1 joerg 4789 1.1 joerg if (!WritingModule) { 4790 1.1 joerg // Write the submodules that were imported, if any. 4791 1.1 joerg struct ModuleInfo { 4792 1.1 joerg uint64_t ID; 4793 1.1 joerg Module *M; 4794 1.1 joerg ModuleInfo(uint64_t ID, Module *M) : ID(ID), M(M) {} 4795 1.1 joerg }; 4796 1.1 joerg llvm::SmallVector<ModuleInfo, 64> Imports; 4797 1.1 joerg for (const auto *I : Context.local_imports()) { 4798 1.1 joerg assert(SubmoduleIDs.find(I->getImportedModule()) != SubmoduleIDs.end()); 4799 1.1 joerg Imports.push_back(ModuleInfo(SubmoduleIDs[I->getImportedModule()], 4800 1.1 joerg I->getImportedModule())); 4801 1.1 joerg } 4802 1.1 joerg 4803 1.1 joerg if (!Imports.empty()) { 4804 1.1 joerg auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) { 4805 1.1 joerg return A.ID < B.ID; 4806 1.1 joerg }; 4807 1.1 joerg auto Eq = [](const ModuleInfo &A, const ModuleInfo &B) { 4808 1.1 joerg return A.ID == B.ID; 4809 1.1 joerg }; 4810 1.1 joerg 4811 1.1 joerg // Sort and deduplicate module IDs. 4812 1.1 joerg llvm::sort(Imports, Cmp); 4813 1.1 joerg Imports.erase(std::unique(Imports.begin(), Imports.end(), Eq), 4814 1.1 joerg Imports.end()); 4815 1.1 joerg 4816 1.1 joerg RecordData ImportedModules; 4817 1.1 joerg for (const auto &Import : Imports) { 4818 1.1 joerg ImportedModules.push_back(Import.ID); 4819 1.1 joerg // FIXME: If the module has macros imported then later has declarations 4820 1.1 joerg // imported, this location won't be the right one as a location for the 4821 1.1 joerg // declaration imports. 4822 1.1 joerg AddSourceLocation(PP.getModuleImportLoc(Import.M), ImportedModules); 4823 1.1 joerg } 4824 1.1 joerg 4825 1.1 joerg Stream.EmitRecord(IMPORTED_MODULES, ImportedModules); 4826 1.1 joerg } 4827 1.1 joerg } 4828 1.1 joerg 4829 1.1 joerg WriteObjCCategories(); 4830 1.1 joerg if(!WritingModule) { 4831 1.1 joerg WriteOptimizePragmaOptions(SemaRef); 4832 1.1 joerg WriteMSStructPragmaOptions(SemaRef); 4833 1.1 joerg WriteMSPointersToMembersPragmaOptions(SemaRef); 4834 1.1 joerg } 4835 1.1 joerg WritePackPragmaOptions(SemaRef); 4836 1.1.1.2 joerg WriteFloatControlPragmaOptions(SemaRef); 4837 1.1 joerg 4838 1.1 joerg // Some simple statistics 4839 1.1 joerg RecordData::value_type Record[] = { 4840 1.1 joerg NumStatements, NumMacros, NumLexicalDeclContexts, NumVisibleDeclContexts}; 4841 1.1 joerg Stream.EmitRecord(STATISTICS, Record); 4842 1.1 joerg Stream.ExitBlock(); 4843 1.1.1.2 joerg Stream.FlushToWord(); 4844 1.1.1.2 joerg ASTBlockRange.second = Stream.GetCurrentBitNo(); 4845 1.1 joerg 4846 1.1 joerg // Write the module file extension blocks. 4847 1.1 joerg for (const auto &ExtWriter : ModuleFileExtensionWriters) 4848 1.1 joerg WriteModuleFileExtension(SemaRef, *ExtWriter); 4849 1.1 joerg 4850 1.1 joerg return writeUnhashedControlBlock(PP, Context); 4851 1.1 joerg } 4852 1.1 joerg 4853 1.1 joerg void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { 4854 1.1 joerg if (DeclUpdates.empty()) 4855 1.1 joerg return; 4856 1.1 joerg 4857 1.1 joerg DeclUpdateMap LocalUpdates; 4858 1.1 joerg LocalUpdates.swap(DeclUpdates); 4859 1.1 joerg 4860 1.1 joerg for (auto &DeclUpdate : LocalUpdates) { 4861 1.1 joerg const Decl *D = DeclUpdate.first; 4862 1.1 joerg 4863 1.1 joerg bool HasUpdatedBody = false; 4864 1.1 joerg RecordData RecordData; 4865 1.1 joerg ASTRecordWriter Record(*this, RecordData); 4866 1.1 joerg for (auto &Update : DeclUpdate.second) { 4867 1.1 joerg DeclUpdateKind Kind = (DeclUpdateKind)Update.getKind(); 4868 1.1 joerg 4869 1.1 joerg // An updated body is emitted last, so that the reader doesn't need 4870 1.1 joerg // to skip over the lazy body to reach statements for other records. 4871 1.1 joerg if (Kind == UPD_CXX_ADDED_FUNCTION_DEFINITION) 4872 1.1 joerg HasUpdatedBody = true; 4873 1.1 joerg else 4874 1.1 joerg Record.push_back(Kind); 4875 1.1 joerg 4876 1.1 joerg switch (Kind) { 4877 1.1 joerg case UPD_CXX_ADDED_IMPLICIT_MEMBER: 4878 1.1 joerg case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: 4879 1.1 joerg case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: 4880 1.1 joerg assert(Update.getDecl() && "no decl to add?"); 4881 1.1 joerg Record.push_back(GetDeclRef(Update.getDecl())); 4882 1.1 joerg break; 4883 1.1 joerg 4884 1.1 joerg case UPD_CXX_ADDED_FUNCTION_DEFINITION: 4885 1.1 joerg break; 4886 1.1 joerg 4887 1.1 joerg case UPD_CXX_POINT_OF_INSTANTIATION: 4888 1.1 joerg // FIXME: Do we need to also save the template specialization kind here? 4889 1.1 joerg Record.AddSourceLocation(Update.getLoc()); 4890 1.1 joerg break; 4891 1.1 joerg 4892 1.1 joerg case UPD_CXX_ADDED_VAR_DEFINITION: { 4893 1.1 joerg const VarDecl *VD = cast<VarDecl>(D); 4894 1.1 joerg Record.push_back(VD->isInline()); 4895 1.1 joerg Record.push_back(VD->isInlineSpecified()); 4896 1.1.1.2 joerg Record.AddVarDeclInit(VD); 4897 1.1 joerg break; 4898 1.1 joerg } 4899 1.1 joerg 4900 1.1 joerg case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: 4901 1.1 joerg Record.AddStmt(const_cast<Expr *>( 4902 1.1 joerg cast<ParmVarDecl>(Update.getDecl())->getDefaultArg())); 4903 1.1 joerg break; 4904 1.1 joerg 4905 1.1 joerg case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER: 4906 1.1 joerg Record.AddStmt( 4907 1.1 joerg cast<FieldDecl>(Update.getDecl())->getInClassInitializer()); 4908 1.1 joerg break; 4909 1.1 joerg 4910 1.1 joerg case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: { 4911 1.1 joerg auto *RD = cast<CXXRecordDecl>(D); 4912 1.1 joerg UpdatedDeclContexts.insert(RD->getPrimaryContext()); 4913 1.1 joerg Record.push_back(RD->isParamDestroyedInCallee()); 4914 1.1 joerg Record.push_back(RD->getArgPassingRestrictions()); 4915 1.1 joerg Record.AddCXXDefinitionData(RD); 4916 1.1 joerg Record.AddOffset(WriteDeclContextLexicalBlock( 4917 1.1 joerg *Context, const_cast<CXXRecordDecl *>(RD))); 4918 1.1 joerg 4919 1.1 joerg // This state is sometimes updated by template instantiation, when we 4920 1.1 joerg // switch from the specialization referring to the template declaration 4921 1.1 joerg // to it referring to the template definition. 4922 1.1 joerg if (auto *MSInfo = RD->getMemberSpecializationInfo()) { 4923 1.1 joerg Record.push_back(MSInfo->getTemplateSpecializationKind()); 4924 1.1 joerg Record.AddSourceLocation(MSInfo->getPointOfInstantiation()); 4925 1.1 joerg } else { 4926 1.1 joerg auto *Spec = cast<ClassTemplateSpecializationDecl>(RD); 4927 1.1 joerg Record.push_back(Spec->getTemplateSpecializationKind()); 4928 1.1 joerg Record.AddSourceLocation(Spec->getPointOfInstantiation()); 4929 1.1 joerg 4930 1.1 joerg // The instantiation might have been resolved to a partial 4931 1.1 joerg // specialization. If so, record which one. 4932 1.1 joerg auto From = Spec->getInstantiatedFrom(); 4933 1.1 joerg if (auto PartialSpec = 4934 1.1 joerg From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) { 4935 1.1 joerg Record.push_back(true); 4936 1.1 joerg Record.AddDeclRef(PartialSpec); 4937 1.1 joerg Record.AddTemplateArgumentList( 4938 1.1 joerg &Spec->getTemplateInstantiationArgs()); 4939 1.1 joerg } else { 4940 1.1 joerg Record.push_back(false); 4941 1.1 joerg } 4942 1.1 joerg } 4943 1.1 joerg Record.push_back(RD->getTagKind()); 4944 1.1 joerg Record.AddSourceLocation(RD->getLocation()); 4945 1.1 joerg Record.AddSourceLocation(RD->getBeginLoc()); 4946 1.1 joerg Record.AddSourceRange(RD->getBraceRange()); 4947 1.1 joerg 4948 1.1 joerg // Instantiation may change attributes; write them all out afresh. 4949 1.1 joerg Record.push_back(D->hasAttrs()); 4950 1.1 joerg if (D->hasAttrs()) 4951 1.1 joerg Record.AddAttributes(D->getAttrs()); 4952 1.1 joerg 4953 1.1 joerg // FIXME: Ensure we don't get here for explicit instantiations. 4954 1.1 joerg break; 4955 1.1 joerg } 4956 1.1 joerg 4957 1.1 joerg case UPD_CXX_RESOLVED_DTOR_DELETE: 4958 1.1 joerg Record.AddDeclRef(Update.getDecl()); 4959 1.1 joerg Record.AddStmt(cast<CXXDestructorDecl>(D)->getOperatorDeleteThisArg()); 4960 1.1 joerg break; 4961 1.1 joerg 4962 1.1.1.2 joerg case UPD_CXX_RESOLVED_EXCEPTION_SPEC: { 4963 1.1.1.2 joerg auto prototype = 4964 1.1.1.2 joerg cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(); 4965 1.1.1.2 joerg Record.writeExceptionSpecInfo(prototype->getExceptionSpecInfo()); 4966 1.1 joerg break; 4967 1.1.1.2 joerg } 4968 1.1 joerg 4969 1.1 joerg case UPD_CXX_DEDUCED_RETURN_TYPE: 4970 1.1 joerg Record.push_back(GetOrCreateTypeID(Update.getType())); 4971 1.1 joerg break; 4972 1.1 joerg 4973 1.1 joerg case UPD_DECL_MARKED_USED: 4974 1.1 joerg break; 4975 1.1 joerg 4976 1.1 joerg case UPD_MANGLING_NUMBER: 4977 1.1 joerg case UPD_STATIC_LOCAL_NUMBER: 4978 1.1 joerg Record.push_back(Update.getNumber()); 4979 1.1 joerg break; 4980 1.1 joerg 4981 1.1 joerg case UPD_DECL_MARKED_OPENMP_THREADPRIVATE: 4982 1.1 joerg Record.AddSourceRange( 4983 1.1 joerg D->getAttr<OMPThreadPrivateDeclAttr>()->getRange()); 4984 1.1 joerg break; 4985 1.1 joerg 4986 1.1 joerg case UPD_DECL_MARKED_OPENMP_ALLOCATE: { 4987 1.1 joerg auto *A = D->getAttr<OMPAllocateDeclAttr>(); 4988 1.1 joerg Record.push_back(A->getAllocatorType()); 4989 1.1 joerg Record.AddStmt(A->getAllocator()); 4990 1.1 joerg Record.AddSourceRange(A->getRange()); 4991 1.1 joerg break; 4992 1.1 joerg } 4993 1.1 joerg 4994 1.1 joerg case UPD_DECL_MARKED_OPENMP_DECLARETARGET: 4995 1.1 joerg Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType()); 4996 1.1 joerg Record.AddSourceRange( 4997 1.1 joerg D->getAttr<OMPDeclareTargetDeclAttr>()->getRange()); 4998 1.1 joerg break; 4999 1.1 joerg 5000 1.1 joerg case UPD_DECL_EXPORTED: 5001 1.1 joerg Record.push_back(getSubmoduleID(Update.getModule())); 5002 1.1 joerg break; 5003 1.1 joerg 5004 1.1 joerg case UPD_ADDED_ATTR_TO_RECORD: 5005 1.1 joerg Record.AddAttributes(llvm::makeArrayRef(Update.getAttr())); 5006 1.1 joerg break; 5007 1.1 joerg } 5008 1.1 joerg } 5009 1.1 joerg 5010 1.1 joerg if (HasUpdatedBody) { 5011 1.1 joerg const auto *Def = cast<FunctionDecl>(D); 5012 1.1 joerg Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION); 5013 1.1 joerg Record.push_back(Def->isInlined()); 5014 1.1 joerg Record.AddSourceLocation(Def->getInnerLocStart()); 5015 1.1 joerg Record.AddFunctionDefinition(Def); 5016 1.1 joerg } 5017 1.1 joerg 5018 1.1 joerg OffsetsRecord.push_back(GetDeclRef(D)); 5019 1.1 joerg OffsetsRecord.push_back(Record.Emit(DECL_UPDATES)); 5020 1.1 joerg } 5021 1.1 joerg } 5022 1.1 joerg 5023 1.1.1.2 joerg void ASTWriter::AddAlignPackInfo(const Sema::AlignPackInfo &Info, 5024 1.1.1.2 joerg RecordDataImpl &Record) { 5025 1.1.1.2 joerg uint32_t Raw = Sema::AlignPackInfo::getRawEncoding(Info); 5026 1.1.1.2 joerg Record.push_back(Raw); 5027 1.1.1.2 joerg } 5028 1.1.1.2 joerg 5029 1.1 joerg void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) { 5030 1.1 joerg uint32_t Raw = Loc.getRawEncoding(); 5031 1.1 joerg Record.push_back((Raw << 1) | (Raw >> 31)); 5032 1.1 joerg } 5033 1.1 joerg 5034 1.1 joerg void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) { 5035 1.1 joerg AddSourceLocation(Range.getBegin(), Record); 5036 1.1 joerg AddSourceLocation(Range.getEnd(), Record); 5037 1.1 joerg } 5038 1.1 joerg 5039 1.1 joerg void ASTRecordWriter::AddAPFloat(const llvm::APFloat &Value) { 5040 1.1 joerg AddAPInt(Value.bitcastToAPInt()); 5041 1.1 joerg } 5042 1.1 joerg 5043 1.1 joerg void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) { 5044 1.1 joerg Record.push_back(getIdentifierRef(II)); 5045 1.1 joerg } 5046 1.1 joerg 5047 1.1 joerg IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) { 5048 1.1 joerg if (!II) 5049 1.1 joerg return 0; 5050 1.1 joerg 5051 1.1 joerg IdentID &ID = IdentifierIDs[II]; 5052 1.1 joerg if (ID == 0) 5053 1.1 joerg ID = NextIdentID++; 5054 1.1 joerg return ID; 5055 1.1 joerg } 5056 1.1 joerg 5057 1.1 joerg MacroID ASTWriter::getMacroRef(MacroInfo *MI, const IdentifierInfo *Name) { 5058 1.1 joerg // Don't emit builtin macros like __LINE__ to the AST file unless they 5059 1.1 joerg // have been redefined by the header (in which case they are not 5060 1.1 joerg // isBuiltinMacro). 5061 1.1 joerg if (!MI || MI->isBuiltinMacro()) 5062 1.1 joerg return 0; 5063 1.1 joerg 5064 1.1 joerg MacroID &ID = MacroIDs[MI]; 5065 1.1 joerg if (ID == 0) { 5066 1.1 joerg ID = NextMacroID++; 5067 1.1 joerg MacroInfoToEmitData Info = { Name, MI, ID }; 5068 1.1 joerg MacroInfosToEmit.push_back(Info); 5069 1.1 joerg } 5070 1.1 joerg return ID; 5071 1.1 joerg } 5072 1.1 joerg 5073 1.1 joerg MacroID ASTWriter::getMacroID(MacroInfo *MI) { 5074 1.1 joerg if (!MI || MI->isBuiltinMacro()) 5075 1.1 joerg return 0; 5076 1.1 joerg 5077 1.1 joerg assert(MacroIDs.find(MI) != MacroIDs.end() && "Macro not emitted!"); 5078 1.1 joerg return MacroIDs[MI]; 5079 1.1 joerg } 5080 1.1 joerg 5081 1.1.1.2 joerg uint32_t ASTWriter::getMacroDirectivesOffset(const IdentifierInfo *Name) { 5082 1.1 joerg return IdentMacroDirectivesOffsetMap.lookup(Name); 5083 1.1 joerg } 5084 1.1 joerg 5085 1.1 joerg void ASTRecordWriter::AddSelectorRef(const Selector SelRef) { 5086 1.1 joerg Record->push_back(Writer->getSelectorRef(SelRef)); 5087 1.1 joerg } 5088 1.1 joerg 5089 1.1 joerg SelectorID ASTWriter::getSelectorRef(Selector Sel) { 5090 1.1 joerg if (Sel.getAsOpaquePtr() == nullptr) { 5091 1.1 joerg return 0; 5092 1.1 joerg } 5093 1.1 joerg 5094 1.1 joerg SelectorID SID = SelectorIDs[Sel]; 5095 1.1 joerg if (SID == 0 && Chain) { 5096 1.1 joerg // This might trigger a ReadSelector callback, which will set the ID for 5097 1.1 joerg // this selector. 5098 1.1 joerg Chain->LoadSelector(Sel); 5099 1.1 joerg SID = SelectorIDs[Sel]; 5100 1.1 joerg } 5101 1.1 joerg if (SID == 0) { 5102 1.1 joerg SID = NextSelectorID++; 5103 1.1 joerg SelectorIDs[Sel] = SID; 5104 1.1 joerg } 5105 1.1 joerg return SID; 5106 1.1 joerg } 5107 1.1 joerg 5108 1.1 joerg void ASTRecordWriter::AddCXXTemporary(const CXXTemporary *Temp) { 5109 1.1 joerg AddDeclRef(Temp->getDestructor()); 5110 1.1 joerg } 5111 1.1 joerg 5112 1.1 joerg void ASTRecordWriter::AddTemplateArgumentLocInfo( 5113 1.1 joerg TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg) { 5114 1.1 joerg switch (Kind) { 5115 1.1 joerg case TemplateArgument::Expression: 5116 1.1 joerg AddStmt(Arg.getAsExpr()); 5117 1.1 joerg break; 5118 1.1 joerg case TemplateArgument::Type: 5119 1.1 joerg AddTypeSourceInfo(Arg.getAsTypeSourceInfo()); 5120 1.1 joerg break; 5121 1.1 joerg case TemplateArgument::Template: 5122 1.1 joerg AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc()); 5123 1.1 joerg AddSourceLocation(Arg.getTemplateNameLoc()); 5124 1.1 joerg break; 5125 1.1 joerg case TemplateArgument::TemplateExpansion: 5126 1.1 joerg AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc()); 5127 1.1 joerg AddSourceLocation(Arg.getTemplateNameLoc()); 5128 1.1 joerg AddSourceLocation(Arg.getTemplateEllipsisLoc()); 5129 1.1 joerg break; 5130 1.1 joerg case TemplateArgument::Null: 5131 1.1 joerg case TemplateArgument::Integral: 5132 1.1 joerg case TemplateArgument::Declaration: 5133 1.1 joerg case TemplateArgument::NullPtr: 5134 1.1 joerg case TemplateArgument::Pack: 5135 1.1 joerg // FIXME: Is this right? 5136 1.1 joerg break; 5137 1.1 joerg } 5138 1.1 joerg } 5139 1.1 joerg 5140 1.1 joerg void ASTRecordWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg) { 5141 1.1 joerg AddTemplateArgument(Arg.getArgument()); 5142 1.1 joerg 5143 1.1 joerg if (Arg.getArgument().getKind() == TemplateArgument::Expression) { 5144 1.1 joerg bool InfoHasSameExpr 5145 1.1 joerg = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr(); 5146 1.1 joerg Record->push_back(InfoHasSameExpr); 5147 1.1 joerg if (InfoHasSameExpr) 5148 1.1 joerg return; // Avoid storing the same expr twice. 5149 1.1 joerg } 5150 1.1 joerg AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo()); 5151 1.1 joerg } 5152 1.1 joerg 5153 1.1 joerg void ASTRecordWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo) { 5154 1.1 joerg if (!TInfo) { 5155 1.1 joerg AddTypeRef(QualType()); 5156 1.1 joerg return; 5157 1.1 joerg } 5158 1.1 joerg 5159 1.1 joerg AddTypeRef(TInfo->getType()); 5160 1.1 joerg AddTypeLoc(TInfo->getTypeLoc()); 5161 1.1 joerg } 5162 1.1 joerg 5163 1.1 joerg void ASTRecordWriter::AddTypeLoc(TypeLoc TL) { 5164 1.1 joerg TypeLocWriter TLW(*this); 5165 1.1 joerg for (; !TL.isNull(); TL = TL.getNextTypeLoc()) 5166 1.1 joerg TLW.Visit(TL); 5167 1.1 joerg } 5168 1.1 joerg 5169 1.1 joerg void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) { 5170 1.1 joerg Record.push_back(GetOrCreateTypeID(T)); 5171 1.1 joerg } 5172 1.1 joerg 5173 1.1 joerg TypeID ASTWriter::GetOrCreateTypeID(QualType T) { 5174 1.1 joerg assert(Context); 5175 1.1 joerg return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx { 5176 1.1 joerg if (T.isNull()) 5177 1.1 joerg return TypeIdx(); 5178 1.1 joerg assert(!T.getLocalFastQualifiers()); 5179 1.1 joerg 5180 1.1 joerg TypeIdx &Idx = TypeIdxs[T]; 5181 1.1 joerg if (Idx.getIndex() == 0) { 5182 1.1 joerg if (DoneWritingDeclsAndTypes) { 5183 1.1 joerg assert(0 && "New type seen after serializing all the types to emit!"); 5184 1.1 joerg return TypeIdx(); 5185 1.1 joerg } 5186 1.1 joerg 5187 1.1 joerg // We haven't seen this type before. Assign it a new ID and put it 5188 1.1 joerg // into the queue of types to emit. 5189 1.1 joerg Idx = TypeIdx(NextTypeID++); 5190 1.1 joerg DeclTypesToEmit.push(T); 5191 1.1 joerg } 5192 1.1 joerg return Idx; 5193 1.1 joerg }); 5194 1.1 joerg } 5195 1.1 joerg 5196 1.1 joerg TypeID ASTWriter::getTypeID(QualType T) const { 5197 1.1 joerg assert(Context); 5198 1.1 joerg return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx { 5199 1.1 joerg if (T.isNull()) 5200 1.1 joerg return TypeIdx(); 5201 1.1 joerg assert(!T.getLocalFastQualifiers()); 5202 1.1 joerg 5203 1.1 joerg TypeIdxMap::const_iterator I = TypeIdxs.find(T); 5204 1.1 joerg assert(I != TypeIdxs.end() && "Type not emitted!"); 5205 1.1 joerg return I->second; 5206 1.1 joerg }); 5207 1.1 joerg } 5208 1.1 joerg 5209 1.1 joerg void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { 5210 1.1 joerg Record.push_back(GetDeclRef(D)); 5211 1.1 joerg } 5212 1.1 joerg 5213 1.1 joerg DeclID ASTWriter::GetDeclRef(const Decl *D) { 5214 1.1 joerg assert(WritingAST && "Cannot request a declaration ID before AST writing"); 5215 1.1 joerg 5216 1.1 joerg if (!D) { 5217 1.1 joerg return 0; 5218 1.1 joerg } 5219 1.1 joerg 5220 1.1 joerg // If D comes from an AST file, its declaration ID is already known and 5221 1.1 joerg // fixed. 5222 1.1 joerg if (D->isFromASTFile()) 5223 1.1 joerg return D->getGlobalID(); 5224 1.1 joerg 5225 1.1 joerg assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer"); 5226 1.1 joerg DeclID &ID = DeclIDs[D]; 5227 1.1 joerg if (ID == 0) { 5228 1.1 joerg if (DoneWritingDeclsAndTypes) { 5229 1.1 joerg assert(0 && "New decl seen after serializing all the decls to emit!"); 5230 1.1 joerg return 0; 5231 1.1 joerg } 5232 1.1 joerg 5233 1.1 joerg // We haven't seen this declaration before. Give it a new ID and 5234 1.1 joerg // enqueue it in the list of declarations to emit. 5235 1.1 joerg ID = NextDeclID++; 5236 1.1 joerg DeclTypesToEmit.push(const_cast<Decl *>(D)); 5237 1.1 joerg } 5238 1.1 joerg 5239 1.1 joerg return ID; 5240 1.1 joerg } 5241 1.1 joerg 5242 1.1 joerg DeclID ASTWriter::getDeclID(const Decl *D) { 5243 1.1 joerg if (!D) 5244 1.1 joerg return 0; 5245 1.1 joerg 5246 1.1 joerg // If D comes from an AST file, its declaration ID is already known and 5247 1.1 joerg // fixed. 5248 1.1 joerg if (D->isFromASTFile()) 5249 1.1 joerg return D->getGlobalID(); 5250 1.1 joerg 5251 1.1 joerg assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!"); 5252 1.1 joerg return DeclIDs[D]; 5253 1.1 joerg } 5254 1.1 joerg 5255 1.1 joerg void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { 5256 1.1 joerg assert(ID); 5257 1.1 joerg assert(D); 5258 1.1 joerg 5259 1.1 joerg SourceLocation Loc = D->getLocation(); 5260 1.1 joerg if (Loc.isInvalid()) 5261 1.1 joerg return; 5262 1.1 joerg 5263 1.1 joerg // We only keep track of the file-level declarations of each file. 5264 1.1 joerg if (!D->getLexicalDeclContext()->isFileContext()) 5265 1.1 joerg return; 5266 1.1 joerg // FIXME: ParmVarDecls that are part of a function type of a parameter of 5267 1.1 joerg // a function/objc method, should not have TU as lexical context. 5268 1.1 joerg // TemplateTemplateParmDecls that are part of an alias template, should not 5269 1.1 joerg // have TU as lexical context. 5270 1.1 joerg if (isa<ParmVarDecl>(D) || isa<TemplateTemplateParmDecl>(D)) 5271 1.1 joerg return; 5272 1.1 joerg 5273 1.1 joerg SourceManager &SM = Context->getSourceManager(); 5274 1.1 joerg SourceLocation FileLoc = SM.getFileLoc(Loc); 5275 1.1 joerg assert(SM.isLocalSourceLocation(FileLoc)); 5276 1.1 joerg FileID FID; 5277 1.1 joerg unsigned Offset; 5278 1.1 joerg std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc); 5279 1.1 joerg if (FID.isInvalid()) 5280 1.1 joerg return; 5281 1.1 joerg assert(SM.getSLocEntry(FID).isFile()); 5282 1.1 joerg 5283 1.1.1.2 joerg std::unique_ptr<DeclIDInFileInfo> &Info = FileDeclIDs[FID]; 5284 1.1 joerg if (!Info) 5285 1.1.1.2 joerg Info = std::make_unique<DeclIDInFileInfo>(); 5286 1.1 joerg 5287 1.1 joerg std::pair<unsigned, serialization::DeclID> LocDecl(Offset, ID); 5288 1.1 joerg LocDeclIDsTy &Decls = Info->DeclIDs; 5289 1.1 joerg 5290 1.1 joerg if (Decls.empty() || Decls.back().first <= Offset) { 5291 1.1 joerg Decls.push_back(LocDecl); 5292 1.1 joerg return; 5293 1.1 joerg } 5294 1.1 joerg 5295 1.1 joerg LocDeclIDsTy::iterator I = 5296 1.1 joerg llvm::upper_bound(Decls, LocDecl, llvm::less_first()); 5297 1.1 joerg 5298 1.1 joerg Decls.insert(I, LocDecl); 5299 1.1 joerg } 5300 1.1 joerg 5301 1.1 joerg unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) { 5302 1.1 joerg assert(needsAnonymousDeclarationNumber(D) && 5303 1.1 joerg "expected an anonymous declaration"); 5304 1.1 joerg 5305 1.1 joerg // Number the anonymous declarations within this context, if we've not 5306 1.1 joerg // already done so. 5307 1.1 joerg auto It = AnonymousDeclarationNumbers.find(D); 5308 1.1 joerg if (It == AnonymousDeclarationNumbers.end()) { 5309 1.1 joerg auto *DC = D->getLexicalDeclContext(); 5310 1.1 joerg numberAnonymousDeclsWithin(DC, [&](const NamedDecl *ND, unsigned Number) { 5311 1.1 joerg AnonymousDeclarationNumbers[ND] = Number; 5312 1.1 joerg }); 5313 1.1 joerg 5314 1.1 joerg It = AnonymousDeclarationNumbers.find(D); 5315 1.1 joerg assert(It != AnonymousDeclarationNumbers.end() && 5316 1.1 joerg "declaration not found within its lexical context"); 5317 1.1 joerg } 5318 1.1 joerg 5319 1.1 joerg return It->second; 5320 1.1 joerg } 5321 1.1 joerg 5322 1.1 joerg void ASTRecordWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, 5323 1.1 joerg DeclarationName Name) { 5324 1.1 joerg switch (Name.getNameKind()) { 5325 1.1 joerg case DeclarationName::CXXConstructorName: 5326 1.1 joerg case DeclarationName::CXXDestructorName: 5327 1.1 joerg case DeclarationName::CXXConversionFunctionName: 5328 1.1.1.2 joerg AddTypeSourceInfo(DNLoc.getNamedTypeInfo()); 5329 1.1 joerg break; 5330 1.1 joerg 5331 1.1 joerg case DeclarationName::CXXOperatorName: 5332 1.1.1.2 joerg AddSourceRange(DNLoc.getCXXOperatorNameRange()); 5333 1.1 joerg break; 5334 1.1 joerg 5335 1.1 joerg case DeclarationName::CXXLiteralOperatorName: 5336 1.1.1.2 joerg AddSourceLocation(DNLoc.getCXXLiteralOperatorNameLoc()); 5337 1.1 joerg break; 5338 1.1 joerg 5339 1.1 joerg case DeclarationName::Identifier: 5340 1.1 joerg case DeclarationName::ObjCZeroArgSelector: 5341 1.1 joerg case DeclarationName::ObjCOneArgSelector: 5342 1.1 joerg case DeclarationName::ObjCMultiArgSelector: 5343 1.1 joerg case DeclarationName::CXXUsingDirective: 5344 1.1 joerg case DeclarationName::CXXDeductionGuideName: 5345 1.1 joerg break; 5346 1.1 joerg } 5347 1.1 joerg } 5348 1.1 joerg 5349 1.1 joerg void ASTRecordWriter::AddDeclarationNameInfo( 5350 1.1 joerg const DeclarationNameInfo &NameInfo) { 5351 1.1 joerg AddDeclarationName(NameInfo.getName()); 5352 1.1 joerg AddSourceLocation(NameInfo.getLoc()); 5353 1.1 joerg AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName()); 5354 1.1 joerg } 5355 1.1 joerg 5356 1.1 joerg void ASTRecordWriter::AddQualifierInfo(const QualifierInfo &Info) { 5357 1.1 joerg AddNestedNameSpecifierLoc(Info.QualifierLoc); 5358 1.1 joerg Record->push_back(Info.NumTemplParamLists); 5359 1.1 joerg for (unsigned i = 0, e = Info.NumTemplParamLists; i != e; ++i) 5360 1.1 joerg AddTemplateParameterList(Info.TemplParamLists[i]); 5361 1.1 joerg } 5362 1.1 joerg 5363 1.1 joerg void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 5364 1.1 joerg // Nested name specifiers usually aren't too long. I think that 8 would 5365 1.1 joerg // typically accommodate the vast majority. 5366 1.1 joerg SmallVector<NestedNameSpecifierLoc , 8> NestedNames; 5367 1.1 joerg 5368 1.1 joerg // Push each of the nested-name-specifiers's onto a stack for 5369 1.1 joerg // serialization in reverse order. 5370 1.1 joerg while (NNS) { 5371 1.1 joerg NestedNames.push_back(NNS); 5372 1.1 joerg NNS = NNS.getPrefix(); 5373 1.1 joerg } 5374 1.1 joerg 5375 1.1 joerg Record->push_back(NestedNames.size()); 5376 1.1 joerg while(!NestedNames.empty()) { 5377 1.1 joerg NNS = NestedNames.pop_back_val(); 5378 1.1 joerg NestedNameSpecifier::SpecifierKind Kind 5379 1.1 joerg = NNS.getNestedNameSpecifier()->getKind(); 5380 1.1 joerg Record->push_back(Kind); 5381 1.1 joerg switch (Kind) { 5382 1.1 joerg case NestedNameSpecifier::Identifier: 5383 1.1 joerg AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier()); 5384 1.1 joerg AddSourceRange(NNS.getLocalSourceRange()); 5385 1.1 joerg break; 5386 1.1 joerg 5387 1.1 joerg case NestedNameSpecifier::Namespace: 5388 1.1 joerg AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace()); 5389 1.1 joerg AddSourceRange(NNS.getLocalSourceRange()); 5390 1.1 joerg break; 5391 1.1 joerg 5392 1.1 joerg case NestedNameSpecifier::NamespaceAlias: 5393 1.1 joerg AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias()); 5394 1.1 joerg AddSourceRange(NNS.getLocalSourceRange()); 5395 1.1 joerg break; 5396 1.1 joerg 5397 1.1 joerg case NestedNameSpecifier::TypeSpec: 5398 1.1 joerg case NestedNameSpecifier::TypeSpecWithTemplate: 5399 1.1 joerg Record->push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); 5400 1.1 joerg AddTypeRef(NNS.getTypeLoc().getType()); 5401 1.1 joerg AddTypeLoc(NNS.getTypeLoc()); 5402 1.1 joerg AddSourceLocation(NNS.getLocalSourceRange().getEnd()); 5403 1.1 joerg break; 5404 1.1 joerg 5405 1.1 joerg case NestedNameSpecifier::Global: 5406 1.1 joerg AddSourceLocation(NNS.getLocalSourceRange().getEnd()); 5407 1.1 joerg break; 5408 1.1 joerg 5409 1.1 joerg case NestedNameSpecifier::Super: 5410 1.1 joerg AddDeclRef(NNS.getNestedNameSpecifier()->getAsRecordDecl()); 5411 1.1 joerg AddSourceRange(NNS.getLocalSourceRange()); 5412 1.1 joerg break; 5413 1.1 joerg } 5414 1.1 joerg } 5415 1.1 joerg } 5416 1.1 joerg 5417 1.1 joerg void ASTRecordWriter::AddTemplateParameterList( 5418 1.1 joerg const TemplateParameterList *TemplateParams) { 5419 1.1 joerg assert(TemplateParams && "No TemplateParams!"); 5420 1.1 joerg AddSourceLocation(TemplateParams->getTemplateLoc()); 5421 1.1 joerg AddSourceLocation(TemplateParams->getLAngleLoc()); 5422 1.1 joerg AddSourceLocation(TemplateParams->getRAngleLoc()); 5423 1.1 joerg 5424 1.1 joerg Record->push_back(TemplateParams->size()); 5425 1.1 joerg for (const auto &P : *TemplateParams) 5426 1.1 joerg AddDeclRef(P); 5427 1.1 joerg if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) { 5428 1.1 joerg Record->push_back(true); 5429 1.1 joerg AddStmt(const_cast<Expr*>(RequiresClause)); 5430 1.1 joerg } else { 5431 1.1 joerg Record->push_back(false); 5432 1.1 joerg } 5433 1.1 joerg } 5434 1.1 joerg 5435 1.1 joerg /// Emit a template argument list. 5436 1.1 joerg void ASTRecordWriter::AddTemplateArgumentList( 5437 1.1 joerg const TemplateArgumentList *TemplateArgs) { 5438 1.1 joerg assert(TemplateArgs && "No TemplateArgs!"); 5439 1.1 joerg Record->push_back(TemplateArgs->size()); 5440 1.1 joerg for (int i = 0, e = TemplateArgs->size(); i != e; ++i) 5441 1.1 joerg AddTemplateArgument(TemplateArgs->get(i)); 5442 1.1 joerg } 5443 1.1 joerg 5444 1.1 joerg void ASTRecordWriter::AddASTTemplateArgumentListInfo( 5445 1.1 joerg const ASTTemplateArgumentListInfo *ASTTemplArgList) { 5446 1.1 joerg assert(ASTTemplArgList && "No ASTTemplArgList!"); 5447 1.1 joerg AddSourceLocation(ASTTemplArgList->LAngleLoc); 5448 1.1 joerg AddSourceLocation(ASTTemplArgList->RAngleLoc); 5449 1.1 joerg Record->push_back(ASTTemplArgList->NumTemplateArgs); 5450 1.1 joerg const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs(); 5451 1.1 joerg for (int i = 0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i) 5452 1.1 joerg AddTemplateArgumentLoc(TemplArgs[i]); 5453 1.1 joerg } 5454 1.1 joerg 5455 1.1 joerg void ASTRecordWriter::AddUnresolvedSet(const ASTUnresolvedSet &Set) { 5456 1.1 joerg Record->push_back(Set.size()); 5457 1.1 joerg for (ASTUnresolvedSet::const_iterator 5458 1.1 joerg I = Set.begin(), E = Set.end(); I != E; ++I) { 5459 1.1 joerg AddDeclRef(I.getDecl()); 5460 1.1 joerg Record->push_back(I.getAccess()); 5461 1.1 joerg } 5462 1.1 joerg } 5463 1.1 joerg 5464 1.1 joerg // FIXME: Move this out of the main ASTRecordWriter interface. 5465 1.1 joerg void ASTRecordWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) { 5466 1.1 joerg Record->push_back(Base.isVirtual()); 5467 1.1 joerg Record->push_back(Base.isBaseOfClass()); 5468 1.1 joerg Record->push_back(Base.getAccessSpecifierAsWritten()); 5469 1.1 joerg Record->push_back(Base.getInheritConstructors()); 5470 1.1 joerg AddTypeSourceInfo(Base.getTypeSourceInfo()); 5471 1.1 joerg AddSourceRange(Base.getSourceRange()); 5472 1.1 joerg AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc() 5473 1.1 joerg : SourceLocation()); 5474 1.1 joerg } 5475 1.1 joerg 5476 1.1 joerg static uint64_t EmitCXXBaseSpecifiers(ASTWriter &W, 5477 1.1 joerg ArrayRef<CXXBaseSpecifier> Bases) { 5478 1.1 joerg ASTWriter::RecordData Record; 5479 1.1 joerg ASTRecordWriter Writer(W, Record); 5480 1.1 joerg Writer.push_back(Bases.size()); 5481 1.1 joerg 5482 1.1 joerg for (auto &Base : Bases) 5483 1.1 joerg Writer.AddCXXBaseSpecifier(Base); 5484 1.1 joerg 5485 1.1 joerg return Writer.Emit(serialization::DECL_CXX_BASE_SPECIFIERS); 5486 1.1 joerg } 5487 1.1 joerg 5488 1.1 joerg // FIXME: Move this out of the main ASTRecordWriter interface. 5489 1.1 joerg void ASTRecordWriter::AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases) { 5490 1.1 joerg AddOffset(EmitCXXBaseSpecifiers(*Writer, Bases)); 5491 1.1 joerg } 5492 1.1 joerg 5493 1.1 joerg static uint64_t 5494 1.1 joerg EmitCXXCtorInitializers(ASTWriter &W, 5495 1.1 joerg ArrayRef<CXXCtorInitializer *> CtorInits) { 5496 1.1 joerg ASTWriter::RecordData Record; 5497 1.1 joerg ASTRecordWriter Writer(W, Record); 5498 1.1 joerg Writer.push_back(CtorInits.size()); 5499 1.1 joerg 5500 1.1 joerg for (auto *Init : CtorInits) { 5501 1.1 joerg if (Init->isBaseInitializer()) { 5502 1.1 joerg Writer.push_back(CTOR_INITIALIZER_BASE); 5503 1.1 joerg Writer.AddTypeSourceInfo(Init->getTypeSourceInfo()); 5504 1.1 joerg Writer.push_back(Init->isBaseVirtual()); 5505 1.1 joerg } else if (Init->isDelegatingInitializer()) { 5506 1.1 joerg Writer.push_back(CTOR_INITIALIZER_DELEGATING); 5507 1.1 joerg Writer.AddTypeSourceInfo(Init->getTypeSourceInfo()); 5508 1.1 joerg } else if (Init->isMemberInitializer()){ 5509 1.1 joerg Writer.push_back(CTOR_INITIALIZER_MEMBER); 5510 1.1 joerg Writer.AddDeclRef(Init->getMember()); 5511 1.1 joerg } else { 5512 1.1 joerg Writer.push_back(CTOR_INITIALIZER_INDIRECT_MEMBER); 5513 1.1 joerg Writer.AddDeclRef(Init->getIndirectMember()); 5514 1.1 joerg } 5515 1.1 joerg 5516 1.1 joerg Writer.AddSourceLocation(Init->getMemberLocation()); 5517 1.1 joerg Writer.AddStmt(Init->getInit()); 5518 1.1 joerg Writer.AddSourceLocation(Init->getLParenLoc()); 5519 1.1 joerg Writer.AddSourceLocation(Init->getRParenLoc()); 5520 1.1 joerg Writer.push_back(Init->isWritten()); 5521 1.1 joerg if (Init->isWritten()) 5522 1.1 joerg Writer.push_back(Init->getSourceOrder()); 5523 1.1 joerg } 5524 1.1 joerg 5525 1.1 joerg return Writer.Emit(serialization::DECL_CXX_CTOR_INITIALIZERS); 5526 1.1 joerg } 5527 1.1 joerg 5528 1.1 joerg // FIXME: Move this out of the main ASTRecordWriter interface. 5529 1.1 joerg void ASTRecordWriter::AddCXXCtorInitializers( 5530 1.1 joerg ArrayRef<CXXCtorInitializer *> CtorInits) { 5531 1.1 joerg AddOffset(EmitCXXCtorInitializers(*Writer, CtorInits)); 5532 1.1 joerg } 5533 1.1 joerg 5534 1.1 joerg void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { 5535 1.1 joerg auto &Data = D->data(); 5536 1.1 joerg Record->push_back(Data.IsLambda); 5537 1.1 joerg 5538 1.1 joerg #define FIELD(Name, Width, Merge) \ 5539 1.1 joerg Record->push_back(Data.Name); 5540 1.1 joerg #include "clang/AST/CXXRecordDeclDefinitionBits.def" 5541 1.1 joerg 5542 1.1 joerg // getODRHash will compute the ODRHash if it has not been previously computed. 5543 1.1 joerg Record->push_back(D->getODRHash()); 5544 1.1.1.2 joerg bool ModulesDebugInfo = 5545 1.1.1.2 joerg Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType(); 5546 1.1 joerg Record->push_back(ModulesDebugInfo); 5547 1.1 joerg if (ModulesDebugInfo) 5548 1.1 joerg Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D)); 5549 1.1 joerg 5550 1.1 joerg // IsLambda bit is already saved. 5551 1.1 joerg 5552 1.1 joerg Record->push_back(Data.NumBases); 5553 1.1 joerg if (Data.NumBases > 0) 5554 1.1 joerg AddCXXBaseSpecifiers(Data.bases()); 5555 1.1 joerg 5556 1.1 joerg // FIXME: Make VBases lazily computed when needed to avoid storing them. 5557 1.1 joerg Record->push_back(Data.NumVBases); 5558 1.1 joerg if (Data.NumVBases > 0) 5559 1.1 joerg AddCXXBaseSpecifiers(Data.vbases()); 5560 1.1 joerg 5561 1.1 joerg AddUnresolvedSet(Data.Conversions.get(*Writer->Context)); 5562 1.1 joerg Record->push_back(Data.ComputedVisibleConversions); 5563 1.1 joerg if (Data.ComputedVisibleConversions) 5564 1.1 joerg AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context)); 5565 1.1 joerg // Data.Definition is the owning decl, no need to write it. 5566 1.1 joerg AddDeclRef(D->getFirstFriend()); 5567 1.1 joerg 5568 1.1 joerg // Add lambda-specific data. 5569 1.1 joerg if (Data.IsLambda) { 5570 1.1 joerg auto &Lambda = D->getLambdaData(); 5571 1.1 joerg Record->push_back(Lambda.Dependent); 5572 1.1 joerg Record->push_back(Lambda.IsGenericLambda); 5573 1.1 joerg Record->push_back(Lambda.CaptureDefault); 5574 1.1 joerg Record->push_back(Lambda.NumCaptures); 5575 1.1 joerg Record->push_back(Lambda.NumExplicitCaptures); 5576 1.1 joerg Record->push_back(Lambda.HasKnownInternalLinkage); 5577 1.1 joerg Record->push_back(Lambda.ManglingNumber); 5578 1.1.1.2 joerg Record->push_back(D->getDeviceLambdaManglingNumber()); 5579 1.1 joerg AddDeclRef(D->getLambdaContextDecl()); 5580 1.1 joerg AddTypeSourceInfo(Lambda.MethodTyInfo); 5581 1.1 joerg for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { 5582 1.1 joerg const LambdaCapture &Capture = Lambda.Captures[I]; 5583 1.1 joerg AddSourceLocation(Capture.getLocation()); 5584 1.1 joerg Record->push_back(Capture.isImplicit()); 5585 1.1 joerg Record->push_back(Capture.getCaptureKind()); 5586 1.1 joerg switch (Capture.getCaptureKind()) { 5587 1.1 joerg case LCK_StarThis: 5588 1.1 joerg case LCK_This: 5589 1.1 joerg case LCK_VLAType: 5590 1.1 joerg break; 5591 1.1 joerg case LCK_ByCopy: 5592 1.1 joerg case LCK_ByRef: 5593 1.1 joerg VarDecl *Var = 5594 1.1 joerg Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr; 5595 1.1 joerg AddDeclRef(Var); 5596 1.1 joerg AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc() 5597 1.1 joerg : SourceLocation()); 5598 1.1 joerg break; 5599 1.1 joerg } 5600 1.1 joerg } 5601 1.1 joerg } 5602 1.1 joerg } 5603 1.1 joerg 5604 1.1.1.2 joerg void ASTRecordWriter::AddVarDeclInit(const VarDecl *VD) { 5605 1.1.1.2 joerg const Expr *Init = VD->getInit(); 5606 1.1.1.2 joerg if (!Init) { 5607 1.1.1.2 joerg push_back(0); 5608 1.1.1.2 joerg return; 5609 1.1.1.2 joerg } 5610 1.1.1.2 joerg 5611 1.1.1.2 joerg unsigned Val = 1; 5612 1.1.1.2 joerg if (EvaluatedStmt *ES = VD->getEvaluatedStmt()) { 5613 1.1.1.2 joerg Val |= (ES->HasConstantInitialization ? 2 : 0); 5614 1.1.1.2 joerg Val |= (ES->HasConstantDestruction ? 4 : 0); 5615 1.1.1.2 joerg // FIXME: Also emit the constant initializer value. 5616 1.1.1.2 joerg } 5617 1.1.1.2 joerg push_back(Val); 5618 1.1.1.2 joerg writeStmtRef(Init); 5619 1.1.1.2 joerg } 5620 1.1.1.2 joerg 5621 1.1 joerg void ASTWriter::ReaderInitialized(ASTReader *Reader) { 5622 1.1 joerg assert(Reader && "Cannot remove chain"); 5623 1.1 joerg assert((!Chain || Chain == Reader) && "Cannot replace chain"); 5624 1.1 joerg assert(FirstDeclID == NextDeclID && 5625 1.1 joerg FirstTypeID == NextTypeID && 5626 1.1 joerg FirstIdentID == NextIdentID && 5627 1.1 joerg FirstMacroID == NextMacroID && 5628 1.1 joerg FirstSubmoduleID == NextSubmoduleID && 5629 1.1 joerg FirstSelectorID == NextSelectorID && 5630 1.1 joerg "Setting chain after writing has started."); 5631 1.1 joerg 5632 1.1 joerg Chain = Reader; 5633 1.1 joerg 5634 1.1 joerg // Note, this will get called multiple times, once one the reader starts up 5635 1.1 joerg // and again each time it's done reading a PCH or module. 5636 1.1 joerg FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls(); 5637 1.1 joerg FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); 5638 1.1 joerg FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); 5639 1.1 joerg FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); 5640 1.1 joerg FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules(); 5641 1.1 joerg FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors(); 5642 1.1 joerg NextDeclID = FirstDeclID; 5643 1.1 joerg NextTypeID = FirstTypeID; 5644 1.1 joerg NextIdentID = FirstIdentID; 5645 1.1 joerg NextMacroID = FirstMacroID; 5646 1.1 joerg NextSelectorID = FirstSelectorID; 5647 1.1 joerg NextSubmoduleID = FirstSubmoduleID; 5648 1.1 joerg } 5649 1.1 joerg 5650 1.1 joerg void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) { 5651 1.1 joerg // Always keep the highest ID. See \p TypeRead() for more information. 5652 1.1 joerg IdentID &StoredID = IdentifierIDs[II]; 5653 1.1 joerg if (ID > StoredID) 5654 1.1 joerg StoredID = ID; 5655 1.1 joerg } 5656 1.1 joerg 5657 1.1 joerg void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) { 5658 1.1 joerg // Always keep the highest ID. See \p TypeRead() for more information. 5659 1.1 joerg MacroID &StoredID = MacroIDs[MI]; 5660 1.1 joerg if (ID > StoredID) 5661 1.1 joerg StoredID = ID; 5662 1.1 joerg } 5663 1.1 joerg 5664 1.1 joerg void ASTWriter::TypeRead(TypeIdx Idx, QualType T) { 5665 1.1 joerg // Always take the highest-numbered type index. This copes with an interesting 5666 1.1 joerg // case for chained AST writing where we schedule writing the type and then, 5667 1.1 joerg // later, deserialize the type from another AST. In this case, we want to 5668 1.1 joerg // keep the higher-numbered entry so that we can properly write it out to 5669 1.1 joerg // the AST file. 5670 1.1 joerg TypeIdx &StoredIdx = TypeIdxs[T]; 5671 1.1 joerg if (Idx.getIndex() >= StoredIdx.getIndex()) 5672 1.1 joerg StoredIdx = Idx; 5673 1.1 joerg } 5674 1.1 joerg 5675 1.1 joerg void ASTWriter::SelectorRead(SelectorID ID, Selector S) { 5676 1.1 joerg // Always keep the highest ID. See \p TypeRead() for more information. 5677 1.1 joerg SelectorID &StoredID = SelectorIDs[S]; 5678 1.1 joerg if (ID > StoredID) 5679 1.1 joerg StoredID = ID; 5680 1.1 joerg } 5681 1.1 joerg 5682 1.1 joerg void ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID, 5683 1.1 joerg MacroDefinitionRecord *MD) { 5684 1.1 joerg assert(MacroDefinitions.find(MD) == MacroDefinitions.end()); 5685 1.1 joerg MacroDefinitions[MD] = ID; 5686 1.1 joerg } 5687 1.1 joerg 5688 1.1 joerg void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) { 5689 1.1 joerg assert(SubmoduleIDs.find(Mod) == SubmoduleIDs.end()); 5690 1.1 joerg SubmoduleIDs[Mod] = ID; 5691 1.1 joerg } 5692 1.1 joerg 5693 1.1 joerg void ASTWriter::CompletedTagDefinition(const TagDecl *D) { 5694 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5695 1.1 joerg assert(D->isCompleteDefinition()); 5696 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5697 1.1 joerg if (auto *RD = dyn_cast<CXXRecordDecl>(D)) { 5698 1.1 joerg // We are interested when a PCH decl is modified. 5699 1.1 joerg if (RD->isFromASTFile()) { 5700 1.1 joerg // A forward reference was mutated into a definition. Rewrite it. 5701 1.1 joerg // FIXME: This happens during template instantiation, should we 5702 1.1 joerg // have created a new definition decl instead ? 5703 1.1 joerg assert(isTemplateInstantiation(RD->getTemplateSpecializationKind()) && 5704 1.1 joerg "completed a tag from another module but not by instantiation?"); 5705 1.1 joerg DeclUpdates[RD].push_back( 5706 1.1 joerg DeclUpdate(UPD_CXX_INSTANTIATED_CLASS_DEFINITION)); 5707 1.1 joerg } 5708 1.1 joerg } 5709 1.1 joerg } 5710 1.1 joerg 5711 1.1 joerg static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) { 5712 1.1 joerg if (D->isFromASTFile()) 5713 1.1 joerg return true; 5714 1.1 joerg 5715 1.1 joerg // The predefined __va_list_tag struct is imported if we imported any decls. 5716 1.1 joerg // FIXME: This is a gross hack. 5717 1.1 joerg return D == D->getASTContext().getVaListTagDecl(); 5718 1.1 joerg } 5719 1.1 joerg 5720 1.1 joerg void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { 5721 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5722 1.1 joerg assert(DC->isLookupContext() && 5723 1.1 joerg "Should not add lookup results to non-lookup contexts!"); 5724 1.1 joerg 5725 1.1 joerg // TU is handled elsewhere. 5726 1.1 joerg if (isa<TranslationUnitDecl>(DC)) 5727 1.1 joerg return; 5728 1.1 joerg 5729 1.1 joerg // Namespaces are handled elsewhere, except for template instantiations of 5730 1.1 joerg // FunctionTemplateDecls in namespaces. We are interested in cases where the 5731 1.1 joerg // local instantiations are added to an imported context. Only happens when 5732 1.1 joerg // adding ADL lookup candidates, for example templated friends. 5733 1.1 joerg if (isa<NamespaceDecl>(DC) && D->getFriendObjectKind() == Decl::FOK_None && 5734 1.1 joerg !isa<FunctionTemplateDecl>(D)) 5735 1.1 joerg return; 5736 1.1 joerg 5737 1.1 joerg // We're only interested in cases where a local declaration is added to an 5738 1.1 joerg // imported context. 5739 1.1 joerg if (D->isFromASTFile() || !isImportedDeclContext(Chain, cast<Decl>(DC))) 5740 1.1 joerg return; 5741 1.1 joerg 5742 1.1 joerg assert(DC == DC->getPrimaryContext() && "added to non-primary context"); 5743 1.1 joerg assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!"); 5744 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5745 1.1 joerg if (UpdatedDeclContexts.insert(DC) && !cast<Decl>(DC)->isFromASTFile()) { 5746 1.1 joerg // We're adding a visible declaration to a predefined decl context. Ensure 5747 1.1 joerg // that we write out all of its lookup results so we don't get a nasty 5748 1.1 joerg // surprise when we try to emit its lookup table. 5749 1.1 joerg for (auto *Child : DC->decls()) 5750 1.1 joerg DeclsToEmitEvenIfUnreferenced.push_back(Child); 5751 1.1 joerg } 5752 1.1 joerg DeclsToEmitEvenIfUnreferenced.push_back(D); 5753 1.1 joerg } 5754 1.1 joerg 5755 1.1 joerg void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { 5756 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5757 1.1 joerg assert(D->isImplicit()); 5758 1.1 joerg 5759 1.1 joerg // We're only interested in cases where a local declaration is added to an 5760 1.1 joerg // imported context. 5761 1.1 joerg if (D->isFromASTFile() || !isImportedDeclContext(Chain, RD)) 5762 1.1 joerg return; 5763 1.1 joerg 5764 1.1 joerg if (!isa<CXXMethodDecl>(D)) 5765 1.1 joerg return; 5766 1.1 joerg 5767 1.1 joerg // A decl coming from PCH was modified. 5768 1.1 joerg assert(RD->isCompleteDefinition()); 5769 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5770 1.1 joerg DeclUpdates[RD].push_back(DeclUpdate(UPD_CXX_ADDED_IMPLICIT_MEMBER, D)); 5771 1.1 joerg } 5772 1.1 joerg 5773 1.1 joerg void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) { 5774 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5775 1.1 joerg assert(!DoneWritingDeclsAndTypes && "Already done writing updates!"); 5776 1.1 joerg if (!Chain) return; 5777 1.1 joerg Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) { 5778 1.1 joerg // If we don't already know the exception specification for this redecl 5779 1.1 joerg // chain, add an update record for it. 5780 1.1 joerg if (isUnresolvedExceptionSpec(cast<FunctionDecl>(D) 5781 1.1 joerg ->getType() 5782 1.1 joerg ->castAs<FunctionProtoType>() 5783 1.1 joerg ->getExceptionSpecType())) 5784 1.1 joerg DeclUpdates[D].push_back(UPD_CXX_RESOLVED_EXCEPTION_SPEC); 5785 1.1 joerg }); 5786 1.1 joerg } 5787 1.1 joerg 5788 1.1 joerg void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { 5789 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5790 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5791 1.1 joerg if (!Chain) return; 5792 1.1 joerg Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) { 5793 1.1 joerg DeclUpdates[D].push_back( 5794 1.1 joerg DeclUpdate(UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType)); 5795 1.1 joerg }); 5796 1.1 joerg } 5797 1.1 joerg 5798 1.1 joerg void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD, 5799 1.1 joerg const FunctionDecl *Delete, 5800 1.1 joerg Expr *ThisArg) { 5801 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5802 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5803 1.1 joerg assert(Delete && "Not given an operator delete"); 5804 1.1 joerg if (!Chain) return; 5805 1.1 joerg Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) { 5806 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_RESOLVED_DTOR_DELETE, Delete)); 5807 1.1 joerg }); 5808 1.1 joerg } 5809 1.1 joerg 5810 1.1 joerg void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { 5811 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5812 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5813 1.1 joerg if (!D->isFromASTFile()) 5814 1.1 joerg return; // Declaration not imported from PCH. 5815 1.1 joerg 5816 1.1 joerg // Implicit function decl from a PCH was defined. 5817 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION)); 5818 1.1 joerg } 5819 1.1 joerg 5820 1.1 joerg void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) { 5821 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5822 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5823 1.1 joerg if (!D->isFromASTFile()) 5824 1.1 joerg return; 5825 1.1 joerg 5826 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_VAR_DEFINITION)); 5827 1.1 joerg } 5828 1.1 joerg 5829 1.1 joerg void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) { 5830 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5831 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5832 1.1 joerg if (!D->isFromASTFile()) 5833 1.1 joerg return; 5834 1.1 joerg 5835 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION)); 5836 1.1 joerg } 5837 1.1 joerg 5838 1.1 joerg void ASTWriter::InstantiationRequested(const ValueDecl *D) { 5839 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5840 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5841 1.1 joerg if (!D->isFromASTFile()) 5842 1.1 joerg return; 5843 1.1 joerg 5844 1.1 joerg // Since the actual instantiation is delayed, this really means that we need 5845 1.1 joerg // to update the instantiation location. 5846 1.1 joerg SourceLocation POI; 5847 1.1 joerg if (auto *VD = dyn_cast<VarDecl>(D)) 5848 1.1 joerg POI = VD->getPointOfInstantiation(); 5849 1.1 joerg else 5850 1.1 joerg POI = cast<FunctionDecl>(D)->getPointOfInstantiation(); 5851 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_POINT_OF_INSTANTIATION, POI)); 5852 1.1 joerg } 5853 1.1 joerg 5854 1.1 joerg void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) { 5855 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5856 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5857 1.1 joerg if (!D->isFromASTFile()) 5858 1.1 joerg return; 5859 1.1 joerg 5860 1.1 joerg DeclUpdates[D].push_back( 5861 1.1 joerg DeclUpdate(UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT, D)); 5862 1.1 joerg } 5863 1.1 joerg 5864 1.1 joerg void ASTWriter::DefaultMemberInitializerInstantiated(const FieldDecl *D) { 5865 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5866 1.1 joerg if (!D->isFromASTFile()) 5867 1.1 joerg return; 5868 1.1 joerg 5869 1.1 joerg DeclUpdates[D].push_back( 5870 1.1 joerg DeclUpdate(UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER, D)); 5871 1.1 joerg } 5872 1.1 joerg 5873 1.1 joerg void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, 5874 1.1 joerg const ObjCInterfaceDecl *IFD) { 5875 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5876 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5877 1.1 joerg if (!IFD->isFromASTFile()) 5878 1.1 joerg return; // Declaration not imported from PCH. 5879 1.1 joerg 5880 1.1 joerg assert(IFD->getDefinition() && "Category on a class without a definition?"); 5881 1.1 joerg ObjCClassesWithCategories.insert( 5882 1.1 joerg const_cast<ObjCInterfaceDecl *>(IFD->getDefinition())); 5883 1.1 joerg } 5884 1.1 joerg 5885 1.1 joerg void ASTWriter::DeclarationMarkedUsed(const Decl *D) { 5886 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5887 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5888 1.1 joerg 5889 1.1 joerg // If there is *any* declaration of the entity that's not from an AST file, 5890 1.1 joerg // we can skip writing the update record. We make sure that isUsed() triggers 5891 1.1 joerg // completion of the redeclaration chain of the entity. 5892 1.1 joerg for (auto Prev = D->getMostRecentDecl(); Prev; Prev = Prev->getPreviousDecl()) 5893 1.1 joerg if (IsLocalDecl(Prev)) 5894 1.1 joerg return; 5895 1.1 joerg 5896 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_USED)); 5897 1.1 joerg } 5898 1.1 joerg 5899 1.1 joerg void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) { 5900 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5901 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5902 1.1 joerg if (!D->isFromASTFile()) 5903 1.1 joerg return; 5904 1.1 joerg 5905 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE)); 5906 1.1 joerg } 5907 1.1 joerg 5908 1.1 joerg void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) { 5909 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5910 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5911 1.1 joerg if (!D->isFromASTFile()) 5912 1.1 joerg return; 5913 1.1 joerg 5914 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_ALLOCATE, A)); 5915 1.1 joerg } 5916 1.1 joerg 5917 1.1 joerg void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D, 5918 1.1 joerg const Attr *Attr) { 5919 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5920 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5921 1.1 joerg if (!D->isFromASTFile()) 5922 1.1 joerg return; 5923 1.1 joerg 5924 1.1 joerg DeclUpdates[D].push_back( 5925 1.1 joerg DeclUpdate(UPD_DECL_MARKED_OPENMP_DECLARETARGET, Attr)); 5926 1.1 joerg } 5927 1.1 joerg 5928 1.1 joerg void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { 5929 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5930 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5931 1.1.1.2 joerg assert(!D->isUnconditionallyVisible() && "expected a hidden declaration"); 5932 1.1 joerg DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M)); 5933 1.1 joerg } 5934 1.1 joerg 5935 1.1 joerg void ASTWriter::AddedAttributeToRecord(const Attr *Attr, 5936 1.1 joerg const RecordDecl *Record) { 5937 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) return; 5938 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5939 1.1 joerg if (!Record->isFromASTFile()) 5940 1.1 joerg return; 5941 1.1 joerg DeclUpdates[Record].push_back(DeclUpdate(UPD_ADDED_ATTR_TO_RECORD, Attr)); 5942 1.1 joerg } 5943 1.1 joerg 5944 1.1 joerg void ASTWriter::AddedCXXTemplateSpecialization( 5945 1.1 joerg const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) { 5946 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5947 1.1 joerg 5948 1.1 joerg if (!TD->getFirstDecl()->isFromASTFile()) 5949 1.1 joerg return; 5950 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) 5951 1.1 joerg return; 5952 1.1 joerg 5953 1.1 joerg DeclsToEmitEvenIfUnreferenced.push_back(D); 5954 1.1 joerg } 5955 1.1 joerg 5956 1.1 joerg void ASTWriter::AddedCXXTemplateSpecialization( 5957 1.1 joerg const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) { 5958 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5959 1.1 joerg 5960 1.1 joerg if (!TD->getFirstDecl()->isFromASTFile()) 5961 1.1 joerg return; 5962 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) 5963 1.1 joerg return; 5964 1.1 joerg 5965 1.1 joerg DeclsToEmitEvenIfUnreferenced.push_back(D); 5966 1.1 joerg } 5967 1.1 joerg 5968 1.1 joerg void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, 5969 1.1 joerg const FunctionDecl *D) { 5970 1.1 joerg assert(!WritingAST && "Already writing the AST!"); 5971 1.1 joerg 5972 1.1 joerg if (!TD->getFirstDecl()->isFromASTFile()) 5973 1.1 joerg return; 5974 1.1 joerg if (Chain && Chain->isProcessingUpdateRecords()) 5975 1.1 joerg return; 5976 1.1 joerg 5977 1.1 joerg DeclsToEmitEvenIfUnreferenced.push_back(D); 5978 1.1 joerg } 5979 1.1 joerg 5980 1.1 joerg //===----------------------------------------------------------------------===// 5981 1.1 joerg //// OMPClause Serialization 5982 1.1 joerg ////===----------------------------------------------------------------------===// 5983 1.1 joerg 5984 1.1.1.2 joerg namespace { 5985 1.1.1.2 joerg 5986 1.1.1.2 joerg class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> { 5987 1.1.1.2 joerg ASTRecordWriter &Record; 5988 1.1.1.2 joerg 5989 1.1.1.2 joerg public: 5990 1.1.1.2 joerg OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {} 5991 1.1.1.2 joerg #define GEN_CLANG_CLAUSE_CLASS 5992 1.1.1.2 joerg #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); 5993 1.1.1.2 joerg #include "llvm/Frontend/OpenMP/OMP.inc" 5994 1.1.1.2 joerg void writeClause(OMPClause *C); 5995 1.1.1.2 joerg void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); 5996 1.1.1.2 joerg void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); 5997 1.1.1.2 joerg }; 5998 1.1.1.2 joerg 5999 1.1.1.2 joerg } 6000 1.1.1.2 joerg 6001 1.1.1.2 joerg void ASTRecordWriter::writeOMPClause(OMPClause *C) { 6002 1.1.1.2 joerg OMPClauseWriter(*this).writeClause(C); 6003 1.1.1.2 joerg } 6004 1.1.1.2 joerg 6005 1.1 joerg void OMPClauseWriter::writeClause(OMPClause *C) { 6006 1.1.1.2 joerg Record.push_back(unsigned(C->getClauseKind())); 6007 1.1 joerg Visit(C); 6008 1.1 joerg Record.AddSourceLocation(C->getBeginLoc()); 6009 1.1 joerg Record.AddSourceLocation(C->getEndLoc()); 6010 1.1 joerg } 6011 1.1 joerg 6012 1.1 joerg void OMPClauseWriter::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) { 6013 1.1.1.2 joerg Record.push_back(uint64_t(C->getCaptureRegion())); 6014 1.1 joerg Record.AddStmt(C->getPreInitStmt()); 6015 1.1 joerg } 6016 1.1 joerg 6017 1.1 joerg void OMPClauseWriter::VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C) { 6018 1.1 joerg VisitOMPClauseWithPreInit(C); 6019 1.1 joerg Record.AddStmt(C->getPostUpdateExpr()); 6020 1.1 joerg } 6021 1.1 joerg 6022 1.1 joerg void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) { 6023 1.1 joerg VisitOMPClauseWithPreInit(C); 6024 1.1.1.2 joerg Record.push_back(uint64_t(C->getNameModifier())); 6025 1.1 joerg Record.AddSourceLocation(C->getNameModifierLoc()); 6026 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6027 1.1 joerg Record.AddStmt(C->getCondition()); 6028 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6029 1.1 joerg } 6030 1.1 joerg 6031 1.1 joerg void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) { 6032 1.1 joerg VisitOMPClauseWithPreInit(C); 6033 1.1 joerg Record.AddStmt(C->getCondition()); 6034 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6035 1.1 joerg } 6036 1.1 joerg 6037 1.1 joerg void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) { 6038 1.1 joerg VisitOMPClauseWithPreInit(C); 6039 1.1 joerg Record.AddStmt(C->getNumThreads()); 6040 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6041 1.1 joerg } 6042 1.1 joerg 6043 1.1 joerg void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) { 6044 1.1 joerg Record.AddStmt(C->getSafelen()); 6045 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6046 1.1 joerg } 6047 1.1 joerg 6048 1.1 joerg void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) { 6049 1.1 joerg Record.AddStmt(C->getSimdlen()); 6050 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6051 1.1 joerg } 6052 1.1 joerg 6053 1.1.1.2 joerg void OMPClauseWriter::VisitOMPSizesClause(OMPSizesClause *C) { 6054 1.1.1.2 joerg Record.push_back(C->getNumSizes()); 6055 1.1.1.2 joerg for (Expr *Size : C->getSizesRefs()) 6056 1.1.1.2 joerg Record.AddStmt(Size); 6057 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6058 1.1.1.2 joerg } 6059 1.1.1.2 joerg 6060 1.1 joerg void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) { 6061 1.1 joerg Record.AddStmt(C->getAllocator()); 6062 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6063 1.1 joerg } 6064 1.1 joerg 6065 1.1 joerg void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) { 6066 1.1 joerg Record.AddStmt(C->getNumForLoops()); 6067 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6068 1.1 joerg } 6069 1.1 joerg 6070 1.1.1.2 joerg void OMPClauseWriter::VisitOMPDetachClause(OMPDetachClause *C) { 6071 1.1.1.2 joerg Record.AddStmt(C->getEventHandler()); 6072 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6073 1.1.1.2 joerg } 6074 1.1.1.2 joerg 6075 1.1 joerg void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) { 6076 1.1.1.2 joerg Record.push_back(unsigned(C->getDefaultKind())); 6077 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6078 1.1 joerg Record.AddSourceLocation(C->getDefaultKindKwLoc()); 6079 1.1 joerg } 6080 1.1 joerg 6081 1.1 joerg void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) { 6082 1.1.1.2 joerg Record.push_back(unsigned(C->getProcBindKind())); 6083 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6084 1.1 joerg Record.AddSourceLocation(C->getProcBindKindKwLoc()); 6085 1.1 joerg } 6086 1.1 joerg 6087 1.1 joerg void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) { 6088 1.1 joerg VisitOMPClauseWithPreInit(C); 6089 1.1 joerg Record.push_back(C->getScheduleKind()); 6090 1.1 joerg Record.push_back(C->getFirstScheduleModifier()); 6091 1.1 joerg Record.push_back(C->getSecondScheduleModifier()); 6092 1.1 joerg Record.AddStmt(C->getChunkSize()); 6093 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6094 1.1 joerg Record.AddSourceLocation(C->getFirstScheduleModifierLoc()); 6095 1.1 joerg Record.AddSourceLocation(C->getSecondScheduleModifierLoc()); 6096 1.1 joerg Record.AddSourceLocation(C->getScheduleKindLoc()); 6097 1.1 joerg Record.AddSourceLocation(C->getCommaLoc()); 6098 1.1 joerg } 6099 1.1 joerg 6100 1.1 joerg void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *C) { 6101 1.1 joerg Record.push_back(C->getLoopNumIterations().size()); 6102 1.1 joerg Record.AddStmt(C->getNumForLoops()); 6103 1.1 joerg for (Expr *NumIter : C->getLoopNumIterations()) 6104 1.1 joerg Record.AddStmt(NumIter); 6105 1.1 joerg for (unsigned I = 0, E = C->getLoopNumIterations().size(); I <E; ++I) 6106 1.1 joerg Record.AddStmt(C->getLoopCounter(I)); 6107 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6108 1.1 joerg } 6109 1.1 joerg 6110 1.1 joerg void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *) {} 6111 1.1 joerg 6112 1.1 joerg void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {} 6113 1.1 joerg 6114 1.1 joerg void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {} 6115 1.1 joerg 6116 1.1 joerg void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {} 6117 1.1 joerg 6118 1.1 joerg void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {} 6119 1.1 joerg 6120 1.1.1.2 joerg void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *C) { 6121 1.1.1.2 joerg Record.push_back(C->isExtended() ? 1 : 0); 6122 1.1.1.2 joerg if (C->isExtended()) { 6123 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6124 1.1.1.2 joerg Record.AddSourceLocation(C->getArgumentLoc()); 6125 1.1.1.2 joerg Record.writeEnum(C->getDependencyKind()); 6126 1.1.1.2 joerg } 6127 1.1.1.2 joerg } 6128 1.1 joerg 6129 1.1 joerg void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {} 6130 1.1 joerg 6131 1.1 joerg void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {} 6132 1.1 joerg 6133 1.1.1.2 joerg void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {} 6134 1.1.1.2 joerg 6135 1.1.1.2 joerg void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {} 6136 1.1.1.2 joerg 6137 1.1.1.2 joerg void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {} 6138 1.1.1.2 joerg 6139 1.1.1.2 joerg void OMPClauseWriter::VisitOMPRelaxedClause(OMPRelaxedClause *) {} 6140 1.1.1.2 joerg 6141 1.1 joerg void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {} 6142 1.1 joerg 6143 1.1 joerg void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {} 6144 1.1 joerg 6145 1.1 joerg void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {} 6146 1.1 joerg 6147 1.1.1.2 joerg void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) { 6148 1.1.1.2 joerg Record.push_back(C->varlist_size()); 6149 1.1.1.2 joerg for (Expr *VE : C->varlists()) 6150 1.1.1.2 joerg Record.AddStmt(VE); 6151 1.1.1.2 joerg Record.writeBool(C->getIsTarget()); 6152 1.1.1.2 joerg Record.writeBool(C->getIsTargetSync()); 6153 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6154 1.1.1.2 joerg Record.AddSourceLocation(C->getVarLoc()); 6155 1.1.1.2 joerg } 6156 1.1.1.2 joerg 6157 1.1.1.2 joerg void OMPClauseWriter::VisitOMPUseClause(OMPUseClause *C) { 6158 1.1.1.2 joerg Record.AddStmt(C->getInteropVar()); 6159 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6160 1.1.1.2 joerg Record.AddSourceLocation(C->getVarLoc()); 6161 1.1.1.2 joerg } 6162 1.1.1.2 joerg 6163 1.1.1.2 joerg void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *C) { 6164 1.1.1.2 joerg Record.AddStmt(C->getInteropVar()); 6165 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6166 1.1.1.2 joerg Record.AddSourceLocation(C->getVarLoc()); 6167 1.1.1.2 joerg } 6168 1.1.1.2 joerg 6169 1.1.1.2 joerg void OMPClauseWriter::VisitOMPNovariantsClause(OMPNovariantsClause *C) { 6170 1.1.1.2 joerg VisitOMPClauseWithPreInit(C); 6171 1.1.1.2 joerg Record.AddStmt(C->getCondition()); 6172 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6173 1.1.1.2 joerg } 6174 1.1.1.2 joerg 6175 1.1.1.2 joerg void OMPClauseWriter::VisitOMPNocontextClause(OMPNocontextClause *C) { 6176 1.1.1.2 joerg VisitOMPClauseWithPreInit(C); 6177 1.1.1.2 joerg Record.AddStmt(C->getCondition()); 6178 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6179 1.1.1.2 joerg } 6180 1.1.1.2 joerg 6181 1.1.1.2 joerg void OMPClauseWriter::VisitOMPFilterClause(OMPFilterClause *C) { 6182 1.1.1.2 joerg VisitOMPClauseWithPreInit(C); 6183 1.1.1.2 joerg Record.AddStmt(C->getThreadID()); 6184 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6185 1.1.1.2 joerg } 6186 1.1.1.2 joerg 6187 1.1 joerg void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { 6188 1.1 joerg Record.push_back(C->varlist_size()); 6189 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6190 1.1 joerg for (auto *VE : C->varlists()) { 6191 1.1 joerg Record.AddStmt(VE); 6192 1.1 joerg } 6193 1.1 joerg for (auto *VE : C->private_copies()) { 6194 1.1 joerg Record.AddStmt(VE); 6195 1.1 joerg } 6196 1.1 joerg } 6197 1.1 joerg 6198 1.1 joerg void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) { 6199 1.1 joerg Record.push_back(C->varlist_size()); 6200 1.1 joerg VisitOMPClauseWithPreInit(C); 6201 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6202 1.1 joerg for (auto *VE : C->varlists()) { 6203 1.1 joerg Record.AddStmt(VE); 6204 1.1 joerg } 6205 1.1 joerg for (auto *VE : C->private_copies()) { 6206 1.1 joerg Record.AddStmt(VE); 6207 1.1 joerg } 6208 1.1 joerg for (auto *VE : C->inits()) { 6209 1.1 joerg Record.AddStmt(VE); 6210 1.1 joerg } 6211 1.1 joerg } 6212 1.1 joerg 6213 1.1 joerg void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) { 6214 1.1 joerg Record.push_back(C->varlist_size()); 6215 1.1 joerg VisitOMPClauseWithPostUpdate(C); 6216 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6217 1.1.1.2 joerg Record.writeEnum(C->getKind()); 6218 1.1.1.2 joerg Record.AddSourceLocation(C->getKindLoc()); 6219 1.1.1.2 joerg Record.AddSourceLocation(C->getColonLoc()); 6220 1.1 joerg for (auto *VE : C->varlists()) 6221 1.1 joerg Record.AddStmt(VE); 6222 1.1 joerg for (auto *E : C->private_copies()) 6223 1.1 joerg Record.AddStmt(E); 6224 1.1 joerg for (auto *E : C->source_exprs()) 6225 1.1 joerg Record.AddStmt(E); 6226 1.1 joerg for (auto *E : C->destination_exprs()) 6227 1.1 joerg Record.AddStmt(E); 6228 1.1 joerg for (auto *E : C->assignment_ops()) 6229 1.1 joerg Record.AddStmt(E); 6230 1.1 joerg } 6231 1.1 joerg 6232 1.1 joerg void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) { 6233 1.1 joerg Record.push_back(C->varlist_size()); 6234 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6235 1.1 joerg for (auto *VE : C->varlists()) 6236 1.1 joerg Record.AddStmt(VE); 6237 1.1 joerg } 6238 1.1 joerg 6239 1.1 joerg void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) { 6240 1.1 joerg Record.push_back(C->varlist_size()); 6241 1.1.1.2 joerg Record.writeEnum(C->getModifier()); 6242 1.1 joerg VisitOMPClauseWithPostUpdate(C); 6243 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6244 1.1.1.2 joerg Record.AddSourceLocation(C->getModifierLoc()); 6245 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6246 1.1 joerg Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); 6247 1.1 joerg Record.AddDeclarationNameInfo(C->getNameInfo()); 6248 1.1 joerg for (auto *VE : C->varlists()) 6249 1.1 joerg Record.AddStmt(VE); 6250 1.1 joerg for (auto *VE : C->privates()) 6251 1.1 joerg Record.AddStmt(VE); 6252 1.1 joerg for (auto *E : C->lhs_exprs()) 6253 1.1 joerg Record.AddStmt(E); 6254 1.1 joerg for (auto *E : C->rhs_exprs()) 6255 1.1 joerg Record.AddStmt(E); 6256 1.1 joerg for (auto *E : C->reduction_ops()) 6257 1.1 joerg Record.AddStmt(E); 6258 1.1.1.2 joerg if (C->getModifier() == clang::OMPC_REDUCTION_inscan) { 6259 1.1.1.2 joerg for (auto *E : C->copy_ops()) 6260 1.1.1.2 joerg Record.AddStmt(E); 6261 1.1.1.2 joerg for (auto *E : C->copy_array_temps()) 6262 1.1.1.2 joerg Record.AddStmt(E); 6263 1.1.1.2 joerg for (auto *E : C->copy_array_elems()) 6264 1.1.1.2 joerg Record.AddStmt(E); 6265 1.1.1.2 joerg } 6266 1.1 joerg } 6267 1.1 joerg 6268 1.1 joerg void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) { 6269 1.1 joerg Record.push_back(C->varlist_size()); 6270 1.1 joerg VisitOMPClauseWithPostUpdate(C); 6271 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6272 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6273 1.1 joerg Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); 6274 1.1 joerg Record.AddDeclarationNameInfo(C->getNameInfo()); 6275 1.1 joerg for (auto *VE : C->varlists()) 6276 1.1 joerg Record.AddStmt(VE); 6277 1.1 joerg for (auto *VE : C->privates()) 6278 1.1 joerg Record.AddStmt(VE); 6279 1.1 joerg for (auto *E : C->lhs_exprs()) 6280 1.1 joerg Record.AddStmt(E); 6281 1.1 joerg for (auto *E : C->rhs_exprs()) 6282 1.1 joerg Record.AddStmt(E); 6283 1.1 joerg for (auto *E : C->reduction_ops()) 6284 1.1 joerg Record.AddStmt(E); 6285 1.1 joerg } 6286 1.1 joerg 6287 1.1 joerg void OMPClauseWriter::VisitOMPInReductionClause(OMPInReductionClause *C) { 6288 1.1 joerg Record.push_back(C->varlist_size()); 6289 1.1 joerg VisitOMPClauseWithPostUpdate(C); 6290 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6291 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6292 1.1 joerg Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); 6293 1.1 joerg Record.AddDeclarationNameInfo(C->getNameInfo()); 6294 1.1 joerg for (auto *VE : C->varlists()) 6295 1.1 joerg Record.AddStmt(VE); 6296 1.1 joerg for (auto *VE : C->privates()) 6297 1.1 joerg Record.AddStmt(VE); 6298 1.1 joerg for (auto *E : C->lhs_exprs()) 6299 1.1 joerg Record.AddStmt(E); 6300 1.1 joerg for (auto *E : C->rhs_exprs()) 6301 1.1 joerg Record.AddStmt(E); 6302 1.1 joerg for (auto *E : C->reduction_ops()) 6303 1.1 joerg Record.AddStmt(E); 6304 1.1 joerg for (auto *E : C->taskgroup_descriptors()) 6305 1.1 joerg Record.AddStmt(E); 6306 1.1 joerg } 6307 1.1 joerg 6308 1.1 joerg void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) { 6309 1.1 joerg Record.push_back(C->varlist_size()); 6310 1.1 joerg VisitOMPClauseWithPostUpdate(C); 6311 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6312 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6313 1.1 joerg Record.push_back(C->getModifier()); 6314 1.1 joerg Record.AddSourceLocation(C->getModifierLoc()); 6315 1.1 joerg for (auto *VE : C->varlists()) { 6316 1.1 joerg Record.AddStmt(VE); 6317 1.1 joerg } 6318 1.1 joerg for (auto *VE : C->privates()) { 6319 1.1 joerg Record.AddStmt(VE); 6320 1.1 joerg } 6321 1.1 joerg for (auto *VE : C->inits()) { 6322 1.1 joerg Record.AddStmt(VE); 6323 1.1 joerg } 6324 1.1 joerg for (auto *VE : C->updates()) { 6325 1.1 joerg Record.AddStmt(VE); 6326 1.1 joerg } 6327 1.1 joerg for (auto *VE : C->finals()) { 6328 1.1 joerg Record.AddStmt(VE); 6329 1.1 joerg } 6330 1.1 joerg Record.AddStmt(C->getStep()); 6331 1.1 joerg Record.AddStmt(C->getCalcStep()); 6332 1.1 joerg for (auto *VE : C->used_expressions()) 6333 1.1 joerg Record.AddStmt(VE); 6334 1.1 joerg } 6335 1.1 joerg 6336 1.1 joerg void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) { 6337 1.1 joerg Record.push_back(C->varlist_size()); 6338 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6339 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6340 1.1 joerg for (auto *VE : C->varlists()) 6341 1.1 joerg Record.AddStmt(VE); 6342 1.1 joerg Record.AddStmt(C->getAlignment()); 6343 1.1 joerg } 6344 1.1 joerg 6345 1.1 joerg void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) { 6346 1.1 joerg Record.push_back(C->varlist_size()); 6347 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6348 1.1 joerg for (auto *VE : C->varlists()) 6349 1.1 joerg Record.AddStmt(VE); 6350 1.1 joerg for (auto *E : C->source_exprs()) 6351 1.1 joerg Record.AddStmt(E); 6352 1.1 joerg for (auto *E : C->destination_exprs()) 6353 1.1 joerg Record.AddStmt(E); 6354 1.1 joerg for (auto *E : C->assignment_ops()) 6355 1.1 joerg Record.AddStmt(E); 6356 1.1 joerg } 6357 1.1 joerg 6358 1.1 joerg void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) { 6359 1.1 joerg Record.push_back(C->varlist_size()); 6360 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6361 1.1 joerg for (auto *VE : C->varlists()) 6362 1.1 joerg Record.AddStmt(VE); 6363 1.1 joerg for (auto *E : C->source_exprs()) 6364 1.1 joerg Record.AddStmt(E); 6365 1.1 joerg for (auto *E : C->destination_exprs()) 6366 1.1 joerg Record.AddStmt(E); 6367 1.1 joerg for (auto *E : C->assignment_ops()) 6368 1.1 joerg Record.AddStmt(E); 6369 1.1 joerg } 6370 1.1 joerg 6371 1.1 joerg void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) { 6372 1.1 joerg Record.push_back(C->varlist_size()); 6373 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6374 1.1 joerg for (auto *VE : C->varlists()) 6375 1.1 joerg Record.AddStmt(VE); 6376 1.1 joerg } 6377 1.1 joerg 6378 1.1.1.2 joerg void OMPClauseWriter::VisitOMPDepobjClause(OMPDepobjClause *C) { 6379 1.1.1.2 joerg Record.AddStmt(C->getDepobj()); 6380 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6381 1.1.1.2 joerg } 6382 1.1.1.2 joerg 6383 1.1 joerg void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { 6384 1.1 joerg Record.push_back(C->varlist_size()); 6385 1.1 joerg Record.push_back(C->getNumLoops()); 6386 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6387 1.1.1.2 joerg Record.AddStmt(C->getModifier()); 6388 1.1 joerg Record.push_back(C->getDependencyKind()); 6389 1.1 joerg Record.AddSourceLocation(C->getDependencyLoc()); 6390 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6391 1.1 joerg for (auto *VE : C->varlists()) 6392 1.1 joerg Record.AddStmt(VE); 6393 1.1 joerg for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) 6394 1.1 joerg Record.AddStmt(C->getLoopData(I)); 6395 1.1 joerg } 6396 1.1 joerg 6397 1.1 joerg void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) { 6398 1.1 joerg VisitOMPClauseWithPreInit(C); 6399 1.1.1.2 joerg Record.writeEnum(C->getModifier()); 6400 1.1 joerg Record.AddStmt(C->getDevice()); 6401 1.1.1.2 joerg Record.AddSourceLocation(C->getModifierLoc()); 6402 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6403 1.1 joerg } 6404 1.1 joerg 6405 1.1 joerg void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { 6406 1.1 joerg Record.push_back(C->varlist_size()); 6407 1.1 joerg Record.push_back(C->getUniqueDeclarationsNum()); 6408 1.1 joerg Record.push_back(C->getTotalComponentListNum()); 6409 1.1 joerg Record.push_back(C->getTotalComponentsNum()); 6410 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6411 1.1.1.2 joerg for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) { 6412 1.1 joerg Record.push_back(C->getMapTypeModifier(I)); 6413 1.1 joerg Record.AddSourceLocation(C->getMapTypeModifierLoc(I)); 6414 1.1 joerg } 6415 1.1 joerg Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); 6416 1.1 joerg Record.AddDeclarationNameInfo(C->getMapperIdInfo()); 6417 1.1 joerg Record.push_back(C->getMapType()); 6418 1.1 joerg Record.AddSourceLocation(C->getMapLoc()); 6419 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6420 1.1 joerg for (auto *E : C->varlists()) 6421 1.1 joerg Record.AddStmt(E); 6422 1.1 joerg for (auto *E : C->mapperlists()) 6423 1.1 joerg Record.AddStmt(E); 6424 1.1 joerg for (auto *D : C->all_decls()) 6425 1.1 joerg Record.AddDeclRef(D); 6426 1.1 joerg for (auto N : C->all_num_lists()) 6427 1.1 joerg Record.push_back(N); 6428 1.1 joerg for (auto N : C->all_lists_sizes()) 6429 1.1 joerg Record.push_back(N); 6430 1.1 joerg for (auto &M : C->all_components()) { 6431 1.1 joerg Record.AddStmt(M.getAssociatedExpression()); 6432 1.1 joerg Record.AddDeclRef(M.getAssociatedDeclaration()); 6433 1.1 joerg } 6434 1.1 joerg } 6435 1.1 joerg 6436 1.1 joerg void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) { 6437 1.1 joerg Record.push_back(C->varlist_size()); 6438 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6439 1.1 joerg Record.AddSourceLocation(C->getColonLoc()); 6440 1.1 joerg Record.AddStmt(C->getAllocator()); 6441 1.1 joerg for (auto *VE : C->varlists()) 6442 1.1 joerg Record.AddStmt(VE); 6443 1.1 joerg } 6444 1.1 joerg 6445 1.1 joerg void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { 6446 1.1 joerg VisitOMPClauseWithPreInit(C); 6447 1.1 joerg Record.AddStmt(C->getNumTeams()); 6448 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6449 1.1 joerg } 6450 1.1 joerg 6451 1.1 joerg void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) { 6452 1.1 joerg VisitOMPClauseWithPreInit(C); 6453 1.1 joerg Record.AddStmt(C->getThreadLimit()); 6454 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6455 1.1 joerg } 6456 1.1 joerg 6457 1.1 joerg void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) { 6458 1.1 joerg VisitOMPClauseWithPreInit(C); 6459 1.1 joerg Record.AddStmt(C->getPriority()); 6460 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6461 1.1 joerg } 6462 1.1 joerg 6463 1.1 joerg void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { 6464 1.1 joerg VisitOMPClauseWithPreInit(C); 6465 1.1 joerg Record.AddStmt(C->getGrainsize()); 6466 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6467 1.1 joerg } 6468 1.1 joerg 6469 1.1 joerg void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) { 6470 1.1 joerg VisitOMPClauseWithPreInit(C); 6471 1.1 joerg Record.AddStmt(C->getNumTasks()); 6472 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6473 1.1 joerg } 6474 1.1 joerg 6475 1.1 joerg void OMPClauseWriter::VisitOMPHintClause(OMPHintClause *C) { 6476 1.1 joerg Record.AddStmt(C->getHint()); 6477 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6478 1.1 joerg } 6479 1.1 joerg 6480 1.1 joerg void OMPClauseWriter::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) { 6481 1.1 joerg VisitOMPClauseWithPreInit(C); 6482 1.1 joerg Record.push_back(C->getDistScheduleKind()); 6483 1.1 joerg Record.AddStmt(C->getChunkSize()); 6484 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6485 1.1 joerg Record.AddSourceLocation(C->getDistScheduleKindLoc()); 6486 1.1 joerg Record.AddSourceLocation(C->getCommaLoc()); 6487 1.1 joerg } 6488 1.1 joerg 6489 1.1 joerg void OMPClauseWriter::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) { 6490 1.1 joerg Record.push_back(C->getDefaultmapKind()); 6491 1.1 joerg Record.push_back(C->getDefaultmapModifier()); 6492 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6493 1.1 joerg Record.AddSourceLocation(C->getDefaultmapModifierLoc()); 6494 1.1 joerg Record.AddSourceLocation(C->getDefaultmapKindLoc()); 6495 1.1 joerg } 6496 1.1 joerg 6497 1.1 joerg void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) { 6498 1.1 joerg Record.push_back(C->varlist_size()); 6499 1.1 joerg Record.push_back(C->getUniqueDeclarationsNum()); 6500 1.1 joerg Record.push_back(C->getTotalComponentListNum()); 6501 1.1 joerg Record.push_back(C->getTotalComponentsNum()); 6502 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6503 1.1.1.2 joerg for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) { 6504 1.1.1.2 joerg Record.push_back(C->getMotionModifier(I)); 6505 1.1.1.2 joerg Record.AddSourceLocation(C->getMotionModifierLoc(I)); 6506 1.1.1.2 joerg } 6507 1.1 joerg Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); 6508 1.1 joerg Record.AddDeclarationNameInfo(C->getMapperIdInfo()); 6509 1.1.1.2 joerg Record.AddSourceLocation(C->getColonLoc()); 6510 1.1 joerg for (auto *E : C->varlists()) 6511 1.1 joerg Record.AddStmt(E); 6512 1.1 joerg for (auto *E : C->mapperlists()) 6513 1.1 joerg Record.AddStmt(E); 6514 1.1 joerg for (auto *D : C->all_decls()) 6515 1.1 joerg Record.AddDeclRef(D); 6516 1.1 joerg for (auto N : C->all_num_lists()) 6517 1.1 joerg Record.push_back(N); 6518 1.1 joerg for (auto N : C->all_lists_sizes()) 6519 1.1 joerg Record.push_back(N); 6520 1.1 joerg for (auto &M : C->all_components()) { 6521 1.1 joerg Record.AddStmt(M.getAssociatedExpression()); 6522 1.1.1.2 joerg Record.writeBool(M.isNonContiguous()); 6523 1.1 joerg Record.AddDeclRef(M.getAssociatedDeclaration()); 6524 1.1 joerg } 6525 1.1 joerg } 6526 1.1 joerg 6527 1.1 joerg void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) { 6528 1.1 joerg Record.push_back(C->varlist_size()); 6529 1.1 joerg Record.push_back(C->getUniqueDeclarationsNum()); 6530 1.1 joerg Record.push_back(C->getTotalComponentListNum()); 6531 1.1 joerg Record.push_back(C->getTotalComponentsNum()); 6532 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6533 1.1.1.2 joerg for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) { 6534 1.1.1.2 joerg Record.push_back(C->getMotionModifier(I)); 6535 1.1.1.2 joerg Record.AddSourceLocation(C->getMotionModifierLoc(I)); 6536 1.1.1.2 joerg } 6537 1.1 joerg Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); 6538 1.1 joerg Record.AddDeclarationNameInfo(C->getMapperIdInfo()); 6539 1.1.1.2 joerg Record.AddSourceLocation(C->getColonLoc()); 6540 1.1 joerg for (auto *E : C->varlists()) 6541 1.1 joerg Record.AddStmt(E); 6542 1.1 joerg for (auto *E : C->mapperlists()) 6543 1.1 joerg Record.AddStmt(E); 6544 1.1 joerg for (auto *D : C->all_decls()) 6545 1.1 joerg Record.AddDeclRef(D); 6546 1.1 joerg for (auto N : C->all_num_lists()) 6547 1.1 joerg Record.push_back(N); 6548 1.1 joerg for (auto N : C->all_lists_sizes()) 6549 1.1 joerg Record.push_back(N); 6550 1.1 joerg for (auto &M : C->all_components()) { 6551 1.1 joerg Record.AddStmt(M.getAssociatedExpression()); 6552 1.1.1.2 joerg Record.writeBool(M.isNonContiguous()); 6553 1.1 joerg Record.AddDeclRef(M.getAssociatedDeclaration()); 6554 1.1 joerg } 6555 1.1 joerg } 6556 1.1 joerg 6557 1.1 joerg void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) { 6558 1.1 joerg Record.push_back(C->varlist_size()); 6559 1.1 joerg Record.push_back(C->getUniqueDeclarationsNum()); 6560 1.1 joerg Record.push_back(C->getTotalComponentListNum()); 6561 1.1 joerg Record.push_back(C->getTotalComponentsNum()); 6562 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6563 1.1 joerg for (auto *E : C->varlists()) 6564 1.1 joerg Record.AddStmt(E); 6565 1.1 joerg for (auto *VE : C->private_copies()) 6566 1.1 joerg Record.AddStmt(VE); 6567 1.1 joerg for (auto *VE : C->inits()) 6568 1.1 joerg Record.AddStmt(VE); 6569 1.1 joerg for (auto *D : C->all_decls()) 6570 1.1 joerg Record.AddDeclRef(D); 6571 1.1 joerg for (auto N : C->all_num_lists()) 6572 1.1 joerg Record.push_back(N); 6573 1.1 joerg for (auto N : C->all_lists_sizes()) 6574 1.1 joerg Record.push_back(N); 6575 1.1 joerg for (auto &M : C->all_components()) { 6576 1.1 joerg Record.AddStmt(M.getAssociatedExpression()); 6577 1.1 joerg Record.AddDeclRef(M.getAssociatedDeclaration()); 6578 1.1 joerg } 6579 1.1 joerg } 6580 1.1 joerg 6581 1.1.1.2 joerg void OMPClauseWriter::VisitOMPUseDeviceAddrClause(OMPUseDeviceAddrClause *C) { 6582 1.1.1.2 joerg Record.push_back(C->varlist_size()); 6583 1.1.1.2 joerg Record.push_back(C->getUniqueDeclarationsNum()); 6584 1.1.1.2 joerg Record.push_back(C->getTotalComponentListNum()); 6585 1.1.1.2 joerg Record.push_back(C->getTotalComponentsNum()); 6586 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6587 1.1.1.2 joerg for (auto *E : C->varlists()) 6588 1.1.1.2 joerg Record.AddStmt(E); 6589 1.1.1.2 joerg for (auto *D : C->all_decls()) 6590 1.1.1.2 joerg Record.AddDeclRef(D); 6591 1.1.1.2 joerg for (auto N : C->all_num_lists()) 6592 1.1.1.2 joerg Record.push_back(N); 6593 1.1.1.2 joerg for (auto N : C->all_lists_sizes()) 6594 1.1.1.2 joerg Record.push_back(N); 6595 1.1.1.2 joerg for (auto &M : C->all_components()) { 6596 1.1.1.2 joerg Record.AddStmt(M.getAssociatedExpression()); 6597 1.1.1.2 joerg Record.AddDeclRef(M.getAssociatedDeclaration()); 6598 1.1.1.2 joerg } 6599 1.1.1.2 joerg } 6600 1.1.1.2 joerg 6601 1.1 joerg void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { 6602 1.1 joerg Record.push_back(C->varlist_size()); 6603 1.1 joerg Record.push_back(C->getUniqueDeclarationsNum()); 6604 1.1 joerg Record.push_back(C->getTotalComponentListNum()); 6605 1.1 joerg Record.push_back(C->getTotalComponentsNum()); 6606 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6607 1.1 joerg for (auto *E : C->varlists()) 6608 1.1 joerg Record.AddStmt(E); 6609 1.1 joerg for (auto *D : C->all_decls()) 6610 1.1 joerg Record.AddDeclRef(D); 6611 1.1 joerg for (auto N : C->all_num_lists()) 6612 1.1 joerg Record.push_back(N); 6613 1.1 joerg for (auto N : C->all_lists_sizes()) 6614 1.1 joerg Record.push_back(N); 6615 1.1 joerg for (auto &M : C->all_components()) { 6616 1.1 joerg Record.AddStmt(M.getAssociatedExpression()); 6617 1.1 joerg Record.AddDeclRef(M.getAssociatedDeclaration()); 6618 1.1 joerg } 6619 1.1 joerg } 6620 1.1 joerg 6621 1.1 joerg void OMPClauseWriter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {} 6622 1.1 joerg 6623 1.1 joerg void OMPClauseWriter::VisitOMPUnifiedSharedMemoryClause( 6624 1.1 joerg OMPUnifiedSharedMemoryClause *) {} 6625 1.1 joerg 6626 1.1 joerg void OMPClauseWriter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {} 6627 1.1 joerg 6628 1.1 joerg void 6629 1.1 joerg OMPClauseWriter::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) { 6630 1.1 joerg } 6631 1.1 joerg 6632 1.1 joerg void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause( 6633 1.1 joerg OMPAtomicDefaultMemOrderClause *C) { 6634 1.1 joerg Record.push_back(C->getAtomicDefaultMemOrderKind()); 6635 1.1 joerg Record.AddSourceLocation(C->getLParenLoc()); 6636 1.1 joerg Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc()); 6637 1.1 joerg } 6638 1.1.1.2 joerg 6639 1.1.1.2 joerg void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) { 6640 1.1.1.2 joerg Record.push_back(C->varlist_size()); 6641 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6642 1.1.1.2 joerg for (auto *VE : C->varlists()) 6643 1.1.1.2 joerg Record.AddStmt(VE); 6644 1.1.1.2 joerg for (auto *E : C->private_refs()) 6645 1.1.1.2 joerg Record.AddStmt(E); 6646 1.1.1.2 joerg } 6647 1.1.1.2 joerg 6648 1.1.1.2 joerg void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) { 6649 1.1.1.2 joerg Record.push_back(C->varlist_size()); 6650 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6651 1.1.1.2 joerg for (auto *VE : C->varlists()) 6652 1.1.1.2 joerg Record.AddStmt(VE); 6653 1.1.1.2 joerg } 6654 1.1.1.2 joerg 6655 1.1.1.2 joerg void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) { 6656 1.1.1.2 joerg Record.push_back(C->varlist_size()); 6657 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6658 1.1.1.2 joerg for (auto *VE : C->varlists()) 6659 1.1.1.2 joerg Record.AddStmt(VE); 6660 1.1.1.2 joerg } 6661 1.1.1.2 joerg 6662 1.1.1.2 joerg void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) { 6663 1.1.1.2 joerg Record.writeEnum(C->getKind()); 6664 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6665 1.1.1.2 joerg Record.AddSourceLocation(C->getKindKwLoc()); 6666 1.1.1.2 joerg } 6667 1.1.1.2 joerg 6668 1.1.1.2 joerg void OMPClauseWriter::VisitOMPUsesAllocatorsClause(OMPUsesAllocatorsClause *C) { 6669 1.1.1.2 joerg Record.push_back(C->getNumberOfAllocators()); 6670 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6671 1.1.1.2 joerg for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) { 6672 1.1.1.2 joerg OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I); 6673 1.1.1.2 joerg Record.AddStmt(Data.Allocator); 6674 1.1.1.2 joerg Record.AddStmt(Data.AllocatorTraits); 6675 1.1.1.2 joerg Record.AddSourceLocation(Data.LParenLoc); 6676 1.1.1.2 joerg Record.AddSourceLocation(Data.RParenLoc); 6677 1.1.1.2 joerg } 6678 1.1.1.2 joerg } 6679 1.1.1.2 joerg 6680 1.1.1.2 joerg void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) { 6681 1.1.1.2 joerg Record.push_back(C->varlist_size()); 6682 1.1.1.2 joerg Record.AddSourceLocation(C->getLParenLoc()); 6683 1.1.1.2 joerg Record.AddStmt(C->getModifier()); 6684 1.1.1.2 joerg Record.AddSourceLocation(C->getColonLoc()); 6685 1.1.1.2 joerg for (Expr *E : C->varlists()) 6686 1.1.1.2 joerg Record.AddStmt(E); 6687 1.1.1.2 joerg } 6688 1.1.1.2 joerg 6689 1.1.1.2 joerg void ASTRecordWriter::writeOMPTraitInfo(const OMPTraitInfo *TI) { 6690 1.1.1.2 joerg writeUInt32(TI->Sets.size()); 6691 1.1.1.2 joerg for (const auto &Set : TI->Sets) { 6692 1.1.1.2 joerg writeEnum(Set.Kind); 6693 1.1.1.2 joerg writeUInt32(Set.Selectors.size()); 6694 1.1.1.2 joerg for (const auto &Selector : Set.Selectors) { 6695 1.1.1.2 joerg writeEnum(Selector.Kind); 6696 1.1.1.2 joerg writeBool(Selector.ScoreOrCondition); 6697 1.1.1.2 joerg if (Selector.ScoreOrCondition) 6698 1.1.1.2 joerg writeExprRef(Selector.ScoreOrCondition); 6699 1.1.1.2 joerg writeUInt32(Selector.Properties.size()); 6700 1.1.1.2 joerg for (const auto &Property : Selector.Properties) 6701 1.1.1.2 joerg writeEnum(Property.Kind); 6702 1.1.1.2 joerg } 6703 1.1.1.2 joerg } 6704 1.1.1.2 joerg } 6705 1.1.1.2 joerg 6706 1.1.1.2 joerg void ASTRecordWriter::writeOMPChildren(OMPChildren *Data) { 6707 1.1.1.2 joerg if (!Data) 6708 1.1.1.2 joerg return; 6709 1.1.1.2 joerg writeUInt32(Data->getNumClauses()); 6710 1.1.1.2 joerg writeUInt32(Data->getNumChildren()); 6711 1.1.1.2 joerg writeBool(Data->hasAssociatedStmt()); 6712 1.1.1.2 joerg for (unsigned I = 0, E = Data->getNumClauses(); I < E; ++I) 6713 1.1.1.2 joerg writeOMPClause(Data->getClauses()[I]); 6714 1.1.1.2 joerg if (Data->hasAssociatedStmt()) 6715 1.1.1.2 joerg AddStmt(Data->getAssociatedStmt()); 6716 1.1.1.2 joerg for (unsigned I = 0, E = Data->getNumChildren(); I < E; ++I) 6717 1.1.1.2 joerg AddStmt(Data->getChildren()[I]); 6718 1.1.1.2 joerg } 6719