Coverage Report

Created: 2021-08-24 07:12

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Lex/PreprocessingRecord.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- PreprocessingRecord.cpp - Record of Preprocessing ------------------===//
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 implements the PreprocessingRecord class, which maintains a record
10
//  of what occurred during preprocessing, and its helpers.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/Lex/PreprocessingRecord.h"
15
#include "clang/Basic/IdentifierTable.h"
16
#include "clang/Basic/LLVM.h"
17
#include "clang/Basic/SourceLocation.h"
18
#include "clang/Basic/SourceManager.h"
19
#include "clang/Basic/TokenKinds.h"
20
#include "clang/Lex/MacroInfo.h"
21
#include "clang/Lex/Token.h"
22
#include "llvm/ADT/DenseMap.h"
23
#include "llvm/ADT/Optional.h"
24
#include "llvm/ADT/StringRef.h"
25
#include "llvm/ADT/iterator_range.h"
26
#include "llvm/Support/Capacity.h"
27
#include "llvm/Support/Casting.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include <algorithm>
30
#include <cassert>
31
#include <cstddef>
32
#include <cstring>
33
#include <iterator>
34
#include <utility>
35
#include <vector>
36
37
using namespace clang;
38
39
12.3k
ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() =
40
    default;
41
42
InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec,
43
                                       InclusionKind Kind, StringRef FileName,
44
                                       bool InQuotes, bool ImportedModule,
45
                                       const FileEntry *File, SourceRange Range)
46
    : PreprocessingDirective(InclusionDirectiveKind, Range), InQuotes(InQuotes),
47
856
      Kind(Kind), ImportedModule(ImportedModule), File(File) {
48
856
  char *Memory = (char *)PPRec.Allocate(FileName.size() + 1, alignof(char));
49
856
  memcpy(Memory, FileName.data(), FileName.size());
50
856
  Memory[FileName.size()] = 0;
51
856
  this->FileName = StringRef(Memory, FileName.size());
52
856
}
53
54
2.10k
PreprocessingRecord::PreprocessingRecord(SourceManager &SM) : SourceMgr(SM) {}
55
56
/// Returns a pair of [Begin, End) iterators of preprocessed entities
57
/// that source range \p Range encompasses.
58
llvm::iterator_range<PreprocessingRecord::iterator>
59
9.57k
PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
60
9.57k
  if (Range.isInvalid())
61
0
    return llvm::make_range(iterator(), iterator());
62
63
9.57k
  if (CachedRangeQuery.Range == Range) {
64
8.40k
    return llvm::make_range(iterator(this, CachedRangeQuery.Result.first),
65
8.40k
                            iterator(this, CachedRangeQuery.Result.second));
66
8.40k
  }
67
68
1.17k
  std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range);
69
70
1.17k
  CachedRangeQuery.Range = Range;
71
1.17k
  CachedRangeQuery.Result = Res;
72
73
1.17k
  return llvm::make_range(iterator(this, Res.first),
74
1.17k
                          iterator(this, Res.second));
75
9.57k
}
76
77
static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID,
78
5.93k
                                           SourceManager &SM) {
79
5.93k
  assert(FID.isValid());
80
5.93k
  if (!PPE)
81
0
    return false;
82
83
5.93k
  SourceLocation Loc = PPE->getSourceRange().getBegin();
84
5.93k
  if (Loc.isInvalid())
85
0
    return false;
86
87
5.93k
  return SM.isInFileID(SM.getFileLoc(Loc), FID);
88
5.93k
}
89
90
/// Returns true if the preprocessed entity that \arg PPEI iterator
91
/// points to is coming from the file \arg FID.
92
///
93
/// Can be used to avoid implicit deserializations of preallocated
94
/// preprocessed entities if we only care about entities of a specific file
95
/// and not from files \#included in the range given at
96
/// \see getPreprocessedEntitiesInRange.
97
9.42k
bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
98
9.42k
  if (FID.isInvalid())
99
0
    return false;
100
101
9.42k
  int Pos = std::distance(iterator(this, 0), PPEI);
102
9.42k
  if (Pos < 0) {
103
9.20k
    if (unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
104
0
      assert(0 && "Out-of bounds loaded preprocessed entity");
105
0
      return false;
106
0
    }
107
9.20k
    assert(ExternalSource && "No external source to load from");
108
0
    unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos;
109
9.20k
    if (PreprocessedEntity *PPE = LoadedPreprocessedEntities[LoadedIndex])
110
5.72k
      return isPreprocessedEntityIfInFileID(PPE, FID, SourceMgr);
111
112
    // See if the external source can see if the entity is in the file without
113
    // deserializing it.
114
3.48k
    Optional<bool> IsInFile =
115
3.48k
        ExternalSource->isPreprocessedEntityInFileID(LoadedIndex, FID);
116
3.48k
    if (IsInFile.hasValue())
117
3.48k
      return IsInFile.getValue();
118
119
    // The external source did not provide a definite answer, go and deserialize
120
    // the entity to check it.
121
0
    return isPreprocessedEntityIfInFileID(
122
0
                                       getLoadedPreprocessedEntity(LoadedIndex),
123
0
                                          FID, SourceMgr);
124
3.48k
  }
125
126
217
  if (unsigned(Pos) >= PreprocessedEntities.size()) {
127
0
    assert(0 && "Out-of bounds local preprocessed entity");
128
0
    return false;
129
0
  }
130
217
  return isPreprocessedEntityIfInFileID(PreprocessedEntities[Pos],
131
217
                                        FID, SourceMgr);
132
217
}
133
134
/// Returns a pair of [Begin, End) iterators of preprocessed entities
135
/// that source range \arg R encompasses.
136
std::pair<int, int>
137
1.17k
PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(SourceRange Range) {
138
1.17k
  assert(Range.isValid());
139
0
  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
140
141
0
  std::pair<unsigned, unsigned>
142
1.17k
    Local = findLocalPreprocessedEntitiesInRange(Range);
143
144
  // Check if range spans local entities.
145
1.17k
  if (!ExternalSource || 
SourceMgr.isLocalSourceLocation(Range.getBegin())900
)
146
343
    return std::make_pair(Local.first, Local.second);
147
148
835
  std::pair<unsigned, unsigned>
149
835
    Loaded = ExternalSource->findPreprocessedEntitiesInRange(Range);
150
151
  // Check if range spans local entities.
152
835
  if (Loaded.first == Loaded.second)
153
43
    return std::make_pair(Local.first, Local.second);
154
155
792
  unsigned TotalLoaded = LoadedPreprocessedEntities.size();
156
157
  // Check if range spans loaded entities.
158
792
  if (Local.first == Local.second)
159
792
    return std::make_pair(int(Loaded.first)-TotalLoaded,
160
792
                          int(Loaded.second)-TotalLoaded);
161
162
  // Range spands loaded and local entities.
163
0
  return std::make_pair(int(Loaded.first)-TotalLoaded, Local.second);
164
792
}
165
166
std::pair<unsigned, unsigned>
167
PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
168
1.17k
                                                      SourceRange Range) const {
169
1.17k
  if (Range.isInvalid())
170
0
    return std::make_pair(0,0);
171
1.17k
  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
172
173
0
  unsigned Begin = findBeginLocalPreprocessedEntity(Range.getBegin());
174
1.17k
  unsigned End = findEndLocalPreprocessedEntity(Range.getEnd());
175
1.17k
  return std::make_pair(Begin, End);
176
1.17k
}
177
178
namespace {
179
180
template <SourceLocation (SourceRange::*getRangeLoc)() const>
181
struct PPEntityComp {
182
  const SourceManager &SM;
183
184
343
  explicit PPEntityComp(const SourceManager &SM) : SM(SM) {}
185
186
  bool operator()(PreprocessedEntity *L, PreprocessedEntity *R) const {
187
    SourceLocation LHS = getLoc(L);
188
    SourceLocation RHS = getLoc(R);
189
    return SM.isBeforeInTranslationUnit(LHS, RHS);
190
  }
191
192
  bool operator()(PreprocessedEntity *L, SourceLocation RHS) const {
193
    SourceLocation LHS = getLoc(L);
194
    return SM.isBeforeInTranslationUnit(LHS, RHS);
195
  }
196
197
2.45k
  bool operator()(SourceLocation LHS, PreprocessedEntity *R) const {
198
2.45k
    SourceLocation RHS = getLoc(R);
199
2.45k
    return SM.isBeforeInTranslationUnit(LHS, RHS);
200
2.45k
  }
201
202
2.45k
  SourceLocation getLoc(PreprocessedEntity *PPE) const {
203
2.45k
    SourceRange Range = PPE->getSourceRange();
204
2.45k
    return (Range.*getRangeLoc)();
205
2.45k
  }
206
};
207
208
} // namespace
209
210
unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
211
1.17k
                                                     SourceLocation Loc) const {
212
1.17k
  if (SourceMgr.isLoadedSourceLocation(Loc))
213
835
    return 0;
214
215
343
  size_t Count = PreprocessedEntities.size();
216
343
  size_t Half;
217
343
  std::vector<PreprocessedEntity *>::const_iterator
218
343
    First = PreprocessedEntities.begin();
219
343
  std::vector<PreprocessedEntity *>::const_iterator I;
220
221
  // Do a binary search manually instead of using std::lower_bound because
222
  // The end locations of entities may be unordered (when a macro expansion
223
  // is inside another macro argument), but for this case it is not important
224
  // whether we get the first macro expansion or its containing macro.
225
2.82k
  while (Count > 0) {
226
2.48k
    Half = Count/2;
227
2.48k
    I = First;
228
2.48k
    std::advance(I, Half);
229
2.48k
    if (SourceMgr.isBeforeInTranslationUnit((*I)->getSourceRange().getEnd(),
230
2.48k
                                            Loc)){
231
2.14k
      First = I;
232
2.14k
      ++First;
233
2.14k
      Count = Count - Half - 1;
234
2.14k
    } else
235
342
      Count = Half;
236
2.48k
  }
237
238
343
  return First - PreprocessedEntities.begin();
239
1.17k
}
240
241
unsigned
242
1.17k
PreprocessingRecord::findEndLocalPreprocessedEntity(SourceLocation Loc) const {
243
1.17k
  if (SourceMgr.isLoadedSourceLocation(Loc))
244
835
    return 0;
245
246
343
  auto I = llvm::upper_bound(PreprocessedEntities, Loc,
247
343
                             PPEntityComp<&SourceRange::getBegin>(SourceMgr));
248
343
  return I - PreprocessedEntities.begin();
249
1.17k
}
250
251
PreprocessingRecord::PPEntityID
252
606k
PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
253
606k
  assert(Entity);
254
0
  SourceLocation BeginLoc = Entity->getSourceRange().getBegin();
255
256
606k
  if (isa<MacroDefinitionRecord>(Entity)) {
257
604k
    assert((PreprocessedEntities.empty() ||
258
604k
            !SourceMgr.isBeforeInTranslationUnit(
259
604k
                BeginLoc,
260
604k
                PreprocessedEntities.back()->getSourceRange().getBegin())) &&
261
604k
           "a macro definition was encountered out-of-order");
262
0
    PreprocessedEntities.push_back(Entity);
263
604k
    return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
264
604k
  }
265
266
  // Check normal case, this entity begin location is after the previous one.
267
2.13k
  if (PreprocessedEntities.empty() ||
268
2.13k
      !SourceMgr.isBeforeInTranslationUnit(BeginLoc,
269
2.12k
                   PreprocessedEntities.back()->getSourceRange().getBegin())) {
270
2.12k
    PreprocessedEntities.push_back(Entity);
271
2.12k
    return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
272
2.12k
  }
273
274
  // The entity's location is not after the previous one; this can happen with
275
  // include directives that form the filename using macros, e.g:
276
  // "#include MACRO(STUFF)"
277
  // or with macro expansions inside macro arguments where the arguments are
278
  // not expanded in the same order as listed, e.g:
279
  // \code
280
  //  #define M1 1
281
  //  #define M2 2
282
  //  #define FM(x,y) y x
283
  //  FM(M1, M2)
284
  // \endcode
285
286
3
  using pp_iter = std::vector<PreprocessedEntity *>::iterator;
287
288
  // Usually there are few macro expansions when defining the filename, do a
289
  // linear search for a few entities.
290
3
  unsigned count = 0;
291
3
  for (pp_iter RI    = PreprocessedEntities.end(),
292
3
               Begin = PreprocessedEntities.begin();
293
7
       RI != Begin && count < 4; 
--RI, ++count4
) {
294
7
    pp_iter I = RI;
295
7
    --I;
296
7
    if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc,
297
7
                                           (*I)->getSourceRange().getBegin())) {
298
3
      pp_iter insertI = PreprocessedEntities.insert(RI, Entity);
299
3
      return getPPEntityID(insertI - PreprocessedEntities.begin(),
300
3
                           /*isLoaded=*/false);
301
3
    }
302
7
  }
303
304
  // Linear search unsuccessful. Do a binary search.
305
0
  pp_iter I =
306
0
      llvm::upper_bound(PreprocessedEntities, BeginLoc,
307
0
                        PPEntityComp<&SourceRange::getBegin>(SourceMgr));
308
0
  pp_iter insertI = PreprocessedEntities.insert(I, Entity);
309
0
  return getPPEntityID(insertI - PreprocessedEntities.begin(),
310
0
                       /*isLoaded=*/false);
311
3
}
312
313
void PreprocessingRecord::SetExternalSource(
314
568
                                    ExternalPreprocessingRecordSource &Source) {
315
568
  assert(!ExternalSource &&
316
568
         "Preprocessing record already has an external source");
317
0
  ExternalSource = &Source;
318
568
}
319
320
720
unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) {
321
720
  unsigned Result = LoadedPreprocessedEntities.size();
322
720
  LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size()
323
720
                                    + NumEntities);
324
720
  return Result;
325
720
}
326
327
82
unsigned PreprocessingRecord::allocateSkippedRanges(unsigned NumRanges) {
328
82
  unsigned Result = SkippedRanges.size();
329
82
  SkippedRanges.resize(SkippedRanges.size() + NumRanges);
330
82
  SkippedRangesAllLoaded = false;
331
82
  return Result;
332
82
}
333
334
281
void PreprocessingRecord::ensureSkippedRangesLoaded() {
335
281
  if (SkippedRangesAllLoaded || 
!ExternalSource14
)
336
267
    return;
337
50
  
for (unsigned Index = 0; 14
Index != SkippedRanges.size();
++Index36
) {
338
36
    if (SkippedRanges[Index].isInvalid())
339
24
      SkippedRanges[Index] = ExternalSource->ReadSkippedRange(Index);
340
36
  }
341
14
  SkippedRangesAllLoaded = true;
342
14
}
343
344
void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
345
39.1k
                                                  MacroDefinitionRecord *Def) {
346
39.1k
  MacroDefinitions[Macro] = Def;
347
39.1k
}
348
349
/// Retrieve the preprocessed entity at the given ID.
350
251k
PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
351
251k
  if (PPID.ID < 0) {
352
60.4k
    unsigned Index = -PPID.ID - 1;
353
60.4k
    assert(Index < LoadedPreprocessedEntities.size() &&
354
60.4k
           "Out-of bounds loaded preprocessed entity");
355
0
    return getLoadedPreprocessedEntity(Index);
356
60.4k
  }
357
358
191k
  if (PPID.ID == 0)
359
0
    return nullptr;
360
191k
  unsigned Index = PPID.ID - 1;
361
191k
  assert(Index < PreprocessedEntities.size() &&
362
191k
         "Out-of bounds local preprocessed entity");
363
0
  return PreprocessedEntities[Index];
364
191k
}
365
366
/// Retrieve the loaded preprocessed entity at the given index.
367
PreprocessedEntity *
368
60.5k
PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
369
60.5k
  assert(Index < LoadedPreprocessedEntities.size() &&
370
60.5k
         "Out-of bounds loaded preprocessed entity");
371
0
  assert(ExternalSource && "No external source to load from");
372
0
  PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index];
373
60.5k
  if (!Entity) {
374
53.6k
    Entity = ExternalSource->ReadPreprocessedEntity(Index);
375
53.6k
    if (!Entity) // Failed to load.
376
0
      Entity = new (*this)
377
0
         PreprocessedEntity(PreprocessedEntity::InvalidKind, SourceRange());
378
53.6k
  }
379
60.5k
  return Entity;
380
60.5k
}
381
382
MacroDefinitionRecord *
383
46.7k
PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
384
46.7k
  llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *>::iterator Pos =
385
46.7k
      MacroDefinitions.find(MI);
386
46.7k
  if (Pos == MacroDefinitions.end())
387
12
    return nullptr;
388
389
46.7k
  return Pos->second;
390
46.7k
}
391
392
void PreprocessingRecord::addMacroExpansion(const Token &Id,
393
                                            const MacroInfo *MI,
394
1.42k
                                            SourceRange Range) {
395
  // We don't record nested macro expansions.
396
1.42k
  if (Id.getLocation().isMacroID())
397
85
    return;
398
399
1.34k
  if (MI->isBuiltinMacro())
400
62
    addPreprocessedEntity(new (*this)
401
62
                              MacroExpansion(Id.getIdentifierInfo(), Range));
402
1.27k
  else if (MacroDefinitionRecord *Def = findMacroDefinition(MI))
403
1.27k
    addPreprocessedEntity(new (*this) MacroExpansion(Def, Range));
404
1.34k
}
405
406
void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok,
407
183
                                const MacroDefinition &MD) {
408
  // This is not actually a macro expansion but record it as a macro reference.
409
183
  if (MD)
410
102
    addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
411
102
                      MacroNameTok.getLocation());
412
183
}
413
414
void PreprocessingRecord::Elifdef(SourceLocation Loc, const Token &MacroNameTok,
415
0
                                  const MacroDefinition &MD) {
416
  // This is not actually a macro expansion but record it as a macro reference.
417
0
  if (MD)
418
0
    addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
419
0
                      MacroNameTok.getLocation());
420
0
}
421
422
void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
423
185
                                 const MacroDefinition &MD) {
424
  // This is not actually a macro expansion but record it as a macro reference.
425
185
  if (MD)
426
48
    addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
427
48
                      MacroNameTok.getLocation());
428
185
}
429
430
void PreprocessingRecord::Elifndef(SourceLocation Loc,
431
                                   const Token &MacroNameTok,
432
0
                                   const MacroDefinition &MD) {
433
  // This is not actually a macro expansion but record it as a macro reference.
434
0
  if (MD)
435
0
    addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
436
0
                      MacroNameTok.getLocation());
437
0
}
438
439
void PreprocessingRecord::Defined(const Token &MacroNameTok,
440
                                  const MacroDefinition &MD,
441
110
                                  SourceRange Range) {
442
  // This is not actually a macro expansion but record it as a macro reference.
443
110
  if (MD)
444
99
    addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
445
99
                      MacroNameTok.getLocation());
446
110
}
447
448
void PreprocessingRecord::SourceRangeSkipped(SourceRange Range,
449
181
                                             SourceLocation EndifLoc) {
450
181
  assert(Range.isValid());
451
0
  SkippedRanges.emplace_back(Range.getBegin(), EndifLoc);
452
181
}
453
454
void PreprocessingRecord::MacroExpands(const Token &Id,
455
                                       const MacroDefinition &MD,
456
                                       SourceRange Range,
457
1.17k
                                       const MacroArgs *Args) {
458
1.17k
  addMacroExpansion(Id, MD.getMacroInfo(), Range);
459
1.17k
}
460
461
void PreprocessingRecord::MacroDefined(const Token &Id,
462
604k
                                       const MacroDirective *MD) {
463
604k
  const MacroInfo *MI = MD->getMacroInfo();
464
604k
  SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
465
604k
  MacroDefinitionRecord *Def =
466
604k
      new (*this) MacroDefinitionRecord(Id.getIdentifierInfo(), R);
467
604k
  addPreprocessedEntity(Def);
468
604k
  MacroDefinitions[MI] = Def;
469
604k
}
470
471
void PreprocessingRecord::MacroUndefined(const Token &Id,
472
                                         const MacroDefinition &MD,
473
70
                                         const MacroDirective *Undef) {
474
70
  MD.forAllDefinitions([&](MacroInfo *MI) 
{ MacroDefinitions.erase(MI); }66
);
475
70
}
476
477
void PreprocessingRecord::InclusionDirective(
478
    SourceLocation HashLoc,
479
    const Token &IncludeTok,
480
    StringRef FileName,
481
    bool IsAngled,
482
    CharSourceRange FilenameRange,
483
    const FileEntry *File,
484
    StringRef SearchPath,
485
    StringRef RelativePath,
486
    const Module *Imported,
487
789
    SrcMgr::CharacteristicKind FileType) {
488
789
  InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
489
490
789
  switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
491
635
  case tok::pp_include:
492
635
    Kind = InclusionDirective::Include;
493
635
    break;
494
495
154
  case tok::pp_import:
496
154
    Kind = InclusionDirective::Import;
497
154
    break;
498
499
0
  case tok::pp_include_next:
500
0
    Kind = InclusionDirective::IncludeNext;
501
0
    break;
502
503
0
  case tok::pp___include_macros:
504
0
    Kind = InclusionDirective::IncludeMacros;
505
0
    break;
506
507
0
  default:
508
0
    llvm_unreachable("Unknown include directive kind");
509
789
  }
510
511
789
  SourceLocation EndLoc;
512
789
  if (!IsAngled) {
513
696
    EndLoc = FilenameRange.getBegin();
514
696
  } else {
515
93
    EndLoc = FilenameRange.getEnd();
516
93
    if (FilenameRange.isCharRange())
517
93
      EndLoc = EndLoc.getLocWithOffset(-1); // the InclusionDirective expects
518
                                            // a token range.
519
93
  }
520
789
  clang::InclusionDirective *ID =
521
789
      new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled,
522
789
                                            (bool)Imported, File,
523
789
                                            SourceRange(HashLoc, EndLoc));
524
789
  addPreprocessedEntity(ID);
525
789
}
526
527
1
size_t PreprocessingRecord::getTotalMemory() const {
528
1
  return BumpAlloc.getTotalMemory()
529
1
    + llvm::capacity_in_bytes(MacroDefinitions)
530
1
    + llvm::capacity_in_bytes(PreprocessedEntities)
531
1
    + llvm::capacity_in_bytes(LoadedPreprocessedEntities)
532
1
    + llvm::capacity_in_bytes(SkippedRanges);
533
1
}