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