Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Basic/Diagnostic.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Diagnostic.cpp - C Language Family Diagnostic Handling -------------===//
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 Diagnostic-related interfaces.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Basic/Diagnostic.h"
14
#include "clang/Basic/CharInfo.h"
15
#include "clang/Basic/DiagnosticError.h"
16
#include "clang/Basic/DiagnosticIDs.h"
17
#include "clang/Basic/DiagnosticOptions.h"
18
#include "clang/Basic/IdentifierTable.h"
19
#include "clang/Basic/PartialDiagnostic.h"
20
#include "clang/Basic/SourceLocation.h"
21
#include "clang/Basic/SourceManager.h"
22
#include "clang/Basic/Specifiers.h"
23
#include "clang/Basic/TokenKinds.h"
24
#include "llvm/ADT/SmallString.h"
25
#include "llvm/ADT/SmallVector.h"
26
#include "llvm/ADT/StringExtras.h"
27
#include "llvm/ADT/StringRef.h"
28
#include "llvm/Support/CrashRecoveryContext.h"
29
#include "llvm/Support/Locale.h"
30
#include "llvm/Support/raw_ostream.h"
31
#include <algorithm>
32
#include <cassert>
33
#include <cstddef>
34
#include <cstdint>
35
#include <cstring>
36
#include <limits>
37
#include <string>
38
#include <utility>
39
#include <vector>
40
41
using namespace clang;
42
43
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
44
120
                                           DiagNullabilityKind nullability) {
45
120
  StringRef string;
46
120
  switch (nullability.first) {
47
120
  case NullabilityKind::NonNull:
48
85
    string = nullability.second ? 
"'nonnull'"11
:
"'_Nonnull'"74
;
49
85
    break;
50
120
51
120
  case NullabilityKind::Nullable:
52
28
    string = nullability.second ? 
"'nullable'"7
:
"'_Nullable'"21
;
53
28
    break;
54
120
55
120
  case NullabilityKind::Unspecified:
56
7
    string = nullability.second ? 
"'null_unspecified'"4
:
"'_Null_unspecified'"3
;
57
7
    break;
58
120
  }
59
120
60
120
  DB.AddString(string);
61
120
  return DB;
62
120
}
63
64
static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
65
                            StringRef Modifier, StringRef Argument,
66
                            ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
67
                            SmallVectorImpl<char> &Output,
68
                            void *Cookie,
69
0
                            ArrayRef<intptr_t> QualTypeVals) {
70
0
  StringRef Str = "<can't format argument>";
71
0
  Output.append(Str.begin(), Str.end());
72
0
}
73
74
DiagnosticsEngine::DiagnosticsEngine(
75
    IntrusiveRefCntPtr<DiagnosticIDs> diags,
76
    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, DiagnosticConsumer *client,
77
    bool ShouldOwnClient)
78
162k
    : Diags(std::move(diags)), DiagOpts(std::move(DiagOpts)) {
79
162k
  setClient(client, ShouldOwnClient);
80
162k
  ArgToStringFn = DummyArgToStringFn;
81
162k
82
162k
  Reset();
83
162k
}
84
85
148k
DiagnosticsEngine::~DiagnosticsEngine() {
86
148k
  // If we own the diagnostic client, destroy it first so that it can access the
87
148k
  // engine from its destructor.
88
148k
  setClient(nullptr);
89
148k
}
90
91
0
void DiagnosticsEngine::dump() const {
92
0
  DiagStatesByLoc.dump(*SourceMgr);
93
0
}
94
95
0
void DiagnosticsEngine::dump(StringRef DiagName) const {
96
0
  DiagStatesByLoc.dump(*SourceMgr, DiagName);
97
0
}
98
99
void DiagnosticsEngine::setClient(DiagnosticConsumer *client,
100
424k
                                  bool ShouldOwnClient) {
101
424k
  Owner.reset(ShouldOwnClient ? 
client376k
:
nullptr48.0k
);
102
424k
  Client = client;
103
424k
}
104
105
247
void DiagnosticsEngine::pushMappings(SourceLocation Loc) {
106
247
  DiagStateOnPushStack.push_back(GetCurDiagState());
107
247
}
108
109
247
bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
110
247
  if (DiagStateOnPushStack.empty())
111
2
    return false;
112
245
113
245
  if (DiagStateOnPushStack.back() != GetCurDiagState()) {
114
240
    // State changed at some point between push/pop.
115
240
    PushDiagStatePoint(DiagStateOnPushStack.back(), Loc);
116
240
  }
117
245
  DiagStateOnPushStack.pop_back();
118
245
  return true;
119
245
}
120
121
168k
void DiagnosticsEngine::Reset() {
122
168k
  ErrorOccurred = false;
123
168k
  UncompilableErrorOccurred = false;
124
168k
  FatalErrorOccurred = false;
125
168k
  UnrecoverableErrorOccurred = false;
126
168k
127
168k
  NumWarnings = 0;
128
168k
  NumErrors = 0;
129
168k
  TrapNumErrorsOccurred = 0;
130
168k
  TrapNumUnrecoverableErrorsOccurred = 0;
131
168k
132
168k
  CurDiagID = std::numeric_limits<unsigned>::max();
133
168k
  LastDiagLevel = DiagnosticIDs::Ignored;
134
168k
  DelayedDiagID = 0;
135
168k
136
168k
  // Clear state related to #pragma diagnostic.
137
168k
  DiagStates.clear();
138
168k
  DiagStatesByLoc.clear();
139
168k
  DiagStateOnPushStack.clear();
140
168k
141
168k
  // Create a DiagState and DiagStatePoint representing diagnostic changes
142
168k
  // through command-line.
143
168k
  DiagStates.emplace_back();
144
168k
  DiagStatesByLoc.appendFirst(&DiagStates.back());
145
168k
}
146
147
void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
148
26
                                             StringRef Arg2) {
149
26
  if (DelayedDiagID)
150
0
    return;
151
26
152
26
  DelayedDiagID = DiagID;
153
26
  DelayedDiagArg1 = Arg1.str();
154
26
  DelayedDiagArg2 = Arg2.str();
155
26
}
156
157
26
void DiagnosticsEngine::ReportDelayed() {
158
26
  unsigned ID = DelayedDiagID;
159
26
  DelayedDiagID = 0;
160
26
  Report(ID) << DelayedDiagArg1 << DelayedDiagArg2;
161
26
}
162
163
168k
void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) {
164
168k
  assert(Files.empty() && "not first");
165
168k
  FirstDiagState = CurDiagState = State;
166
168k
  CurDiagStateLoc = SourceLocation();
167
168k
}
168
169
void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr,
170
                                             SourceLocation Loc,
171
585
                                             DiagState *State) {
172
585
  CurDiagState = State;
173
585
  CurDiagStateLoc = Loc;
174
585
175
585
  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
176
585
  unsigned Offset = Decomp.second;
177
3.26k
  for (File *F = getFile(SrcMgr, Decomp.first); F;
178
2.67k
       Offset = F->ParentOffset, F = F->Parent) {
179
2.67k
    F->HasLocalTransitions = true;
180
2.67k
    auto &Last = F->StateTransitions.back();
181
2.67k
    assert(Last.Offset <= Offset && "state transitions added out of order");
182
2.67k
183
2.67k
    if (Last.Offset == Offset) {
184
1.60k
      if (Last.State == State)
185
0
        break;
186
1.60k
      Last.State = State;
187
1.60k
      continue;
188
1.60k
    }
189
1.07k
190
1.07k
    F->StateTransitions.push_back({State, Offset});
191
1.07k
  }
192
585
}
193
194
DiagnosticsEngine::DiagState *
195
DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr,
196
99.6M
                                        SourceLocation Loc) const {
197
99.6M
  // Common case: we have not seen any diagnostic pragmas.
198
99.6M
  if (Files.empty())
199
98.5M
    return FirstDiagState;
200
1.03M
201
1.03M
  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
202
1.03M
  const File *F = getFile(SrcMgr, Decomp.first);
203
1.03M
  return F->lookup(Decomp.second);
204
1.03M
}
205
206
DiagnosticsEngine::DiagState *
207
1.11M
DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
208
1.11M
  auto OnePastIt =
209
1.15M
      llvm::partition_point(StateTransitions, [=](const DiagStatePoint &P) {
210
1.15M
        return P.Offset <= Offset;
211
1.15M
      });
212
1.11M
  assert(OnePastIt != StateTransitions.begin() && "missing initial state");
213
1.11M
  return OnePastIt[-1].State;
214
1.11M
}
215
216
DiagnosticsEngine::DiagStateMap::File *
217
DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
218
1.11M
                                         FileID ID) const {
219
1.11M
  // Get or insert the File for this ID.
220
1.11M
  auto Range = Files.equal_range(ID);
221
1.11M
  if (Range.first != Range.second)
222
1.03M
    return &Range.first->second;
223
83.6k
  auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second;
224
83.6k
225
83.6k
  // We created a new File; look up the diagnostic state at the start of it and
226
83.6k
  // initialize it.
227
83.6k
  if (ID.isValid()) {
228
83.1k
    std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedIncludedLoc(ID);
229
83.1k
    F.Parent = getFile(SrcMgr, Decomp.first);
230
83.1k
    F.ParentOffset = Decomp.second;
231
83.1k
    F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0});
232
83.1k
  } else {
233
548
    // This is the (imaginary) root file into which we pretend all top-level
234
548
    // files are included; it descends from the initial state.
235
548
    //
236
548
    // FIXME: This doesn't guarantee that we use the same ordering as
237
548
    // isBeforeInTranslationUnit in the cases where someone invented another
238
548
    // top-level file and added diagnostic pragmas to it. See the code at the
239
548
    // end of isBeforeInTranslationUnit for the quirks it deals with.
240
548
    F.StateTransitions.push_back({FirstDiagState, 0});
241
548
  }
242
83.6k
  return &F;
243
83.6k
}
244
245
void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr,
246
0
                                           StringRef DiagName) const {
247
0
  llvm::errs() << "diagnostic state at ";
248
0
  CurDiagStateLoc.print(llvm::errs(), SrcMgr);
249
0
  llvm::errs() << ": " << CurDiagState << "\n";
250
0
251
0
  for (auto &F : Files) {
252
0
    FileID ID = F.first;
253
0
    File &File = F.second;
254
0
255
0
    bool PrintedOuterHeading = false;
256
0
    auto PrintOuterHeading = [&] {
257
0
      if (PrintedOuterHeading) return;
258
0
      PrintedOuterHeading = true;
259
0
260
0
      llvm::errs() << "File " << &File << " <FileID " << ID.getHashValue()
261
0
                   << ">: " << SrcMgr.getBuffer(ID)->getBufferIdentifier();
262
0
      if (F.second.Parent) {
263
0
        std::pair<FileID, unsigned> Decomp =
264
0
            SrcMgr.getDecomposedIncludedLoc(ID);
265
0
        assert(File.ParentOffset == Decomp.second);
266
0
        llvm::errs() << " parent " << File.Parent << " <FileID "
267
0
                     << Decomp.first.getHashValue() << "> ";
268
0
        SrcMgr.getLocForStartOfFile(Decomp.first)
269
0
              .getLocWithOffset(Decomp.second)
270
0
              .print(llvm::errs(), SrcMgr);
271
0
      }
272
0
      if (File.HasLocalTransitions)
273
0
        llvm::errs() << " has_local_transitions";
274
0
      llvm::errs() << "\n";
275
0
    };
276
0
277
0
    if (DiagName.empty())
278
0
      PrintOuterHeading();
279
0
280
0
    for (DiagStatePoint &Transition : File.StateTransitions) {
281
0
      bool PrintedInnerHeading = false;
282
0
      auto PrintInnerHeading = [&] {
283
0
        if (PrintedInnerHeading) return;
284
0
        PrintedInnerHeading = true;
285
0
286
0
        PrintOuterHeading();
287
0
        llvm::errs() << "  ";
288
0
        SrcMgr.getLocForStartOfFile(ID)
289
0
              .getLocWithOffset(Transition.Offset)
290
0
              .print(llvm::errs(), SrcMgr);
291
0
        llvm::errs() << ": state " << Transition.State << ":\n";
292
0
      };
293
0
294
0
      if (DiagName.empty())
295
0
        PrintInnerHeading();
296
0
297
0
      for (auto &Mapping : *Transition.State) {
298
0
        StringRef Option =
299
0
            DiagnosticIDs::getWarningOptionForDiag(Mapping.first);
300
0
        if (!DiagName.empty() && DiagName != Option)
301
0
          continue;
302
0
303
0
        PrintInnerHeading();
304
0
        llvm::errs() << "    ";
305
0
        if (Option.empty())
306
0
          llvm::errs() << "<unknown " << Mapping.first << ">";
307
0
        else
308
0
          llvm::errs() << Option;
309
0
        llvm::errs() << ": ";
310
0
311
0
        switch (Mapping.second.getSeverity()) {
312
0
        case diag::Severity::Ignored: llvm::errs() << "ignored"; break;
313
0
        case diag::Severity::Remark: llvm::errs() << "remark"; break;
314
0
        case diag::Severity::Warning: llvm::errs() << "warning"; break;
315
0
        case diag::Severity::Error: llvm::errs() << "error"; break;
316
0
        case diag::Severity::Fatal: llvm::errs() << "fatal"; break;
317
0
        }
318
0
319
0
        if (!Mapping.second.isUser())
320
0
          llvm::errs() << " default";
321
0
        if (Mapping.second.isPragma())
322
0
          llvm::errs() << " pragma";
323
0
        if (Mapping.second.hasNoWarningAsError())
324
0
          llvm::errs() << " no-error";
325
0
        if (Mapping.second.hasNoErrorAsFatal())
326
0
          llvm::errs() << " no-fatal";
327
0
        if (Mapping.second.wasUpgradedFromWarning())
328
0
          llvm::errs() << " overruled";
329
0
        llvm::errs() << "\n";
330
0
      }
331
0
    }
332
0
  }
333
0
}
334
335
void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,
336
585
                                           SourceLocation Loc) {
337
585
  assert(Loc.isValid() && "Adding invalid loc point");
338
585
  DiagStatesByLoc.append(*SourceMgr, Loc, State);
339
585
}
340
341
void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
342
2.16M
                                    SourceLocation L) {
343
2.16M
  assert(Diag < diag::DIAG_UPPER_LIMIT &&
344
2.16M
         "Can only map builtin diagnostics");
345
2.16M
  assert((Diags->isBuiltinWarningOrExtension(Diag) ||
346
2.16M
          (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
347
2.16M
         "Cannot map errors into warnings!");
348
2.16M
  assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
349
2.16M
350
2.16M
  // Don't allow a mapping to a warning override an error/fatal mapping.
351
2.16M
  bool WasUpgradedFromWarning = false;
352
2.16M
  if (Map == diag::Severity::Warning) {
353
1.81M
    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
354
1.81M
    if (Info.getSeverity() == diag::Severity::Error ||
355
1.81M
        
Info.getSeverity() == diag::Severity::Fatal1.75M
) {
356
55.6k
      Map = Info.getSeverity();
357
55.6k
      WasUpgradedFromWarning = true;
358
55.6k
    }
359
1.81M
  }
360
2.16M
  DiagnosticMapping Mapping = makeUserMapping(Map, L);
361
2.16M
  Mapping.setUpgradedFromWarning(WasUpgradedFromWarning);
362
2.16M
363
2.16M
  // Common case; setting all the diagnostics of a group in one place.
364
2.16M
  if ((L.isInvalid() || 
L == DiagStatesByLoc.getCurDiagStateLoc()45.2k
) &&
365
2.16M
      
DiagStatesByLoc.getCurDiagState()2.16M
) {
366
2.16M
    // FIXME: This is theoretically wrong: if the current state is shared with
367
2.16M
    // some other location (via push/pop) we will change the state for that
368
2.16M
    // other location as well. This cannot currently happen, as we can't update
369
2.16M
    // the diagnostic state at the same location at which we pop.
370
2.16M
    DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping);
371
2.16M
    return;
372
2.16M
  }
373
344
374
344
  // A diagnostic pragma occurred, create a new DiagState initialized with
375
344
  // the current one and a new DiagStatePoint to record at which location
376
344
  // the new state became active.
377
344
  DiagStates.push_back(*GetCurDiagState());
378
344
  DiagStates.back().setMapping(Diag, Mapping);
379
344
  PushDiagStatePoint(&DiagStates.back(), L);
380
344
}
381
382
bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
383
                                            StringRef Group, diag::Severity Map,
384
100k
                                            SourceLocation Loc) {
385
100k
  // Get the diagnostics in this group.
386
100k
  SmallVector<diag::kind, 256> GroupDiags;
387
100k
  if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags))
388
42
    return true;
389
100k
390
100k
  // Set the mapping.
391
100k
  for (diag::kind Diag : GroupDiags)
392
2.08M
    setSeverity(Diag, Map, Loc);
393
100k
394
100k
  return false;
395
100k
}
396
397
bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
398
43.2k
                                                         bool Enabled) {
399
43.2k
  // If we are enabling this feature, just set the diagnostic mappings to map to
400
43.2k
  // errors.
401
43.2k
  if (Enabled)
402
42.7k
    return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
403
42.7k
                               diag::Severity::Error);
404
482
405
482
  // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
406
482
  // potentially downgrade anything already mapped to be a warning.
407
482
408
482
  // Get the diagnostics in this group.
409
482
  SmallVector<diag::kind, 8> GroupDiags;
410
482
  if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
411
482
                                   GroupDiags))
412
0
    return true;
413
482
414
482
  // Perform the mapping change.
415
3.21k
  
for (diag::kind Diag : GroupDiags)482
{
416
3.21k
    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
417
3.21k
418
3.21k
    if (Info.getSeverity() == diag::Severity::Error ||
419
3.21k
        
Info.getSeverity() == diag::Severity::Fatal1.40k
)
420
1.81k
      Info.setSeverity(diag::Severity::Warning);
421
3.21k
422
3.21k
    Info.setNoWarningAsError(true);
423
3.21k
  }
424
482
425
482
  return false;
426
482
}
427
428
bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
429
1
                                                       bool Enabled) {
430
1
  // If we are enabling this feature, just set the diagnostic mappings to map to
431
1
  // fatal errors.
432
1
  if (Enabled)
433
1
    return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
434
1
                               diag::Severity::Fatal);
435
0
436
0
  // Otherwise, we want to set the diagnostic mapping's "no Wfatal-errors" bit,
437
0
  // and potentially downgrade anything already mapped to be a fatal error.
438
0
439
0
  // Get the diagnostics in this group.
440
0
  SmallVector<diag::kind, 8> GroupDiags;
441
0
  if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
442
0
                                   GroupDiags))
443
0
    return true;
444
0
445
0
  // Perform the mapping change.
446
0
  for (diag::kind Diag : GroupDiags) {
447
0
    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
448
0
449
0
    if (Info.getSeverity() == diag::Severity::Fatal)
450
0
      Info.setSeverity(diag::Severity::Error);
451
0
452
0
    Info.setNoErrorAsFatal(true);
453
0
  }
454
0
455
0
  return false;
456
0
}
457
458
void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor,
459
                                          diag::Severity Map,
460
44
                                          SourceLocation Loc) {
461
44
  // Get all the diagnostics.
462
44
  std::vector<diag::kind> AllDiags;
463
44
  DiagnosticIDs::getAllDiagnostics(Flavor, AllDiags);
464
44
465
44
  // Set the mapping.
466
44
  for (diag::kind Diag : AllDiags)
467
176k
    if (Diags->isBuiltinWarningOrExtension(Diag))
468
78.6k
      setSeverity(Diag, Map, Loc);
469
44
}
470
471
150
void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
472
150
  assert(CurDiagID == std::numeric_limits<unsigned>::max() &&
473
150
         "Multiple diagnostics in flight at once!");
474
150
475
150
  CurDiagLoc = storedDiag.getLocation();
476
150
  CurDiagID = storedDiag.getID();
477
150
  NumDiagArgs = 0;
478
150
479
150
  DiagRanges.clear();
480
150
  DiagRanges.append(storedDiag.range_begin(), storedDiag.range_end());
481
150
482
150
  DiagFixItHints.clear();
483
150
  DiagFixItHints.append(storedDiag.fixit_begin(), storedDiag.fixit_end());
484
150
485
150
  assert(Client && "DiagnosticConsumer not set!");
486
150
  Level DiagLevel = storedDiag.getLevel();
487
150
  Diagnostic Info(this, storedDiag.getMessage());
488
150
  Client->HandleDiagnostic(DiagLevel, Info);
489
150
  if (Client->IncludeInDiagnosticCounts()) {
490
150
    if (DiagLevel == DiagnosticsEngine::Warning)
491
1
      ++NumWarnings;
492
150
  }
493
150
494
150
  CurDiagID = std::numeric_limits<unsigned>::max();
495
150
}
496
497
4.18M
bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) {
498
4.18M
  assert(getClient() && "DiagnosticClient not set!");
499
4.18M
500
4.18M
  bool Emitted;
501
4.18M
  if (Force) {
502
192
    Diagnostic Info(this);
503
192
504
192
    // Figure out the diagnostic level of this message.
505
192
    DiagnosticIDs::Level DiagLevel
506
192
      = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this);
507
192
508
192
    Emitted = (DiagLevel != DiagnosticIDs::Ignored);
509
192
    if (Emitted) {
510
192
      // Emit the diagnostic regardless of suppression level.
511
192
      Diags->EmitDiag(*this, DiagLevel);
512
192
    }
513
4.18M
  } else {
514
4.18M
    // Process the diagnostic, sending the accumulated information to the
515
4.18M
    // DiagnosticConsumer.
516
4.18M
    Emitted = ProcessDiag();
517
4.18M
  }
518
4.18M
519
4.18M
  // Clear out the current diagnostic object.
520
4.18M
  Clear();
521
4.18M
522
4.18M
  // If there was a delayed diagnostic, emit it now.
523
4.18M
  if (!Force && 
DelayedDiagID4.18M
)
524
26
    ReportDelayed();
525
4.18M
526
4.18M
  return Emitted;
527
4.18M
}
528
529
151k
DiagnosticConsumer::~DiagnosticConsumer() = default;
530
531
void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
532
252k
                                        const Diagnostic &Info) {
533
252k
  if (!IncludeInDiagnosticCounts())
534
4
    return;
535
252k
536
252k
  if (DiagLevel == DiagnosticsEngine::Warning)
537
55.8k
    ++NumWarnings;
538
197k
  else if (DiagLevel >= DiagnosticsEngine::Error)
539
113k
    ++NumErrors;
540
252k
}
541
542
/// ModifierIs - Return true if the specified modifier matches specified string.
543
template <std::size_t StrLen>
544
static bool ModifierIs(const char *Modifier, unsigned ModifierLen,
545
504k
                       const char (&Str)[StrLen]) {
546
504k
  return StrLen-1 == ModifierLen && 
memcmp(Modifier, Str, StrLen-1) == 0133k
;
547
504k
}
Diagnostic.cpp:bool ModifierIs<5ul>(char const*, unsigned int, char const (&) [5ul])
Line
Count
Source
545
333k
                       const char (&Str)[StrLen]) {
546
333k
  return StrLen-1 == ModifierLen && 
memcmp(Modifier, Str, StrLen-1) == 09.47k
;
547
333k
}
Diagnostic.cpp:bool ModifierIs<7ul>(char const*, unsigned int, char const (&) [7ul])
Line
Count
Source
545
143k
                       const char (&Str)[StrLen]) {
546
143k
  return StrLen-1 == ModifierLen && 
memcmp(Modifier, Str, StrLen-1) == 0117k
;
547
143k
}
Diagnostic.cpp:bool ModifierIs<2ul>(char const*, unsigned int, char const (&) [2ul])
Line
Count
Source
545
15.6k
                       const char (&Str)[StrLen]) {
546
15.6k
  return StrLen-1 == ModifierLen && 
memcmp(Modifier, Str, StrLen-1) == 01.27k
;
547
15.6k
}
Diagnostic.cpp:bool ModifierIs<8ul>(char const*, unsigned int, char const (&) [8ul])
Line
Count
Source
545
12.3k
                       const char (&Str)[StrLen]) {
546
12.3k
  return StrLen-1 == ModifierLen && 
memcmp(Modifier, Str, StrLen-1) == 05.39k
;
547
12.3k
}
548
549
/// ScanForward - Scans forward, looking for the given character, skipping
550
/// nested clauses and escaped characters.
551
344k
static const char *ScanFormat(const char *I, const char *E, char Target) {
552
344k
  unsigned Depth = 0;
553
344k
554
15.1M
  for ( ; I != E; 
++I14.8M
) {
555
15.1M
    if (Depth == 0 && 
*I == Target12.6M
)
return I317k
;
556
14.8M
    if (Depth != 0 && 
*I == '}'2.52M
)
Depth--62.7k
;
557
14.8M
558
14.8M
    if (*I == '%') {
559
184k
      I++;
560
184k
      if (I == E) 
break0
;
561
184k
562
184k
      // Escaped characters get implicitly skipped here.
563
184k
564
184k
      // Format specifier.
565
184k
      if (!isDigit(*I) && 
!isPunctuation(*I)83.2k
) {
566
439k
        for (I++; I != E && !isDigit(*I) && 
*I != '{'419k
;
I++357k
)
;357k
567
82.8k
        if (I == E) 
break0
;
568
82.8k
        if (*I == '{')
569
62.7k
          Depth++;
570
82.8k
      }
571
184k
    }
572
14.8M
  }
573
344k
  
return E27.7k
;
574
344k
}
575
576
/// HandleSelectModifier - Handle the integer 'select' modifier.  This is used
577
/// like this:  %select{foo|bar|baz}2.  This means that the integer argument
578
/// "%2" has a value from 0-2.  If the value is 0, the diagnostic prints 'foo'.
579
/// If the value is 1, it prints 'bar'.  If it has the value 2, it prints 'baz'.
580
/// This is very useful for certain classes of variant diagnostics.
581
static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo,
582
                                 const char *Argument, unsigned ArgumentLen,
583
113k
                                 SmallVectorImpl<char> &OutStr) {
584
113k
  const char *ArgumentEnd = Argument+ArgumentLen;
585
113k
586
113k
  // Skip over 'ValNo' |'s.
587
189k
  while (ValNo) {
588
75.9k
    const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|');
589
75.9k
    assert(NextVal != ArgumentEnd && "Value for integer select modifier was"
590
75.9k
           " larger than the number of options in the diagnostic string!");
591
75.9k
    Argument = NextVal+1;  // Skip this string.
592
75.9k
    --ValNo;
593
75.9k
  }
594
113k
595
113k
  // Get the end of the value.  This is either the } or the |.
596
113k
  const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|');
597
113k
598
113k
  // Recursively format the result of the select clause into the output string.
599
113k
  DInfo.FormatDiagnostic(Argument, EndPtr, OutStr);
600
113k
}
601
602
/// HandleIntegerSModifier - Handle the integer 's' modifier.  This adds the
603
/// letter 's' to the string if the value is not 1.  This is used in cases like
604
/// this:  "you idiot, you have %4 parameter%s4!".
605
static void HandleIntegerSModifier(unsigned ValNo,
606
1.27k
                                   SmallVectorImpl<char> &OutStr) {
607
1.27k
  if (ValNo != 1)
608
716
    OutStr.push_back('s');
609
1.27k
}
610
611
/// HandleOrdinalModifier - Handle the integer 'ord' modifier.  This
612
/// prints the ordinal form of the given integer, with 1 corresponding
613
/// to the first ordinal.  Currently this is hard-coded to use the
614
/// English form.
615
static void HandleOrdinalModifier(unsigned ValNo,
616
5.39k
                                  SmallVectorImpl<char> &OutStr) {
617
5.39k
  assert(ValNo != 0 && "ValNo must be strictly positive!");
618
5.39k
619
5.39k
  llvm::raw_svector_ostream Out(OutStr);
620
5.39k
621
5.39k
  // We could use text forms for the first N ordinals, but the numeric
622
5.39k
  // forms are actually nicer in diagnostics because they stand out.
623
5.39k
  Out << ValNo << llvm::getOrdinalSuffix(ValNo);
624
5.39k
}
625
626
/// PluralNumber - Parse an unsigned integer and advance Start.
627
2.49k
static unsigned PluralNumber(const char *&Start, const char *End) {
628
2.49k
  // Programming 101: Parse a decimal number :-)
629
2.49k
  unsigned Val = 0;
630
4.99k
  while (Start != End && 
*Start >= '0'2.51k
&&
*Start <= '9'2.50k
) {
631
2.49k
    Val *= 10;
632
2.49k
    Val += *Start - '0';
633
2.49k
    ++Start;
634
2.49k
  }
635
2.49k
  return Val;
636
2.49k
}
637
638
/// TestPluralRange - Test if Val is in the parsed range. Modifies Start.
639
2.48k
static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) {
640
2.48k
  if (*Start != '[') {
641
2.48k
    unsigned Ref = PluralNumber(Start, End);
642
2.48k
    return Ref == Val;
643
2.48k
  }
644
7
645
7
  ++Start;
646
7
  unsigned Low = PluralNumber(Start, End);
647
7
  assert(*Start == ',' && "Bad plural expression syntax: expected ,");
648
7
  ++Start;
649
7
  unsigned High = PluralNumber(Start, End);
650
7
  assert(*Start == ']' && "Bad plural expression syntax: expected )");
651
7
  ++Start;
652
7
  return Low <= Val && Val <= High;
653
7
}
654
655
/// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier.
656
3.52k
static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
657
3.52k
  // Empty condition?
658
3.52k
  if (*Start == ':')
659
1.03k
    return true;
660
2.48k
661
2.48k
  while (true) {
662
2.48k
    char C = *Start;
663
2.48k
    if (C == '%') {
664
0
      // Modulo expression
665
0
      ++Start;
666
0
      unsigned Arg = PluralNumber(Start, End);
667
0
      assert(*Start == '=' && "Bad plural expression syntax: expected =");
668
0
      ++Start;
669
0
      unsigned ValMod = ValNo % Arg;
670
0
      if (TestPluralRange(ValMod, Start, End))
671
0
        return true;
672
2.48k
    } else {
673
2.48k
      assert((C == '[' || (C >= '0' && C <= '9')) &&
674
2.48k
             "Bad plural expression syntax: unexpected character");
675
2.48k
      // Range expression
676
2.48k
      if (TestPluralRange(ValNo, Start, End))
677
1.01k
        return true;
678
1.47k
    }
679
1.47k
680
1.47k
    // Scan for next or-expr part.
681
1.47k
    Start = std::find(Start, End, ',');
682
1.47k
    if (Start == End)
683
1.47k
      break;
684
0
    ++Start;
685
0
  }
686
2.48k
  
return false1.47k
;
687
2.48k
}
688
689
/// HandlePluralModifier - Handle the integer 'plural' modifier. This is used
690
/// for complex plural forms, or in languages where all plurals are complex.
691
/// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are
692
/// conditions that are tested in order, the form corresponding to the first
693
/// that applies being emitted. The empty condition is always true, making the
694
/// last form a default case.
695
/// Conditions are simple boolean expressions, where n is the number argument.
696
/// Here are the rules.
697
/// condition  := expression | empty
698
/// empty      :=                             -> always true
699
/// expression := numeric [',' expression]    -> logical or
700
/// numeric    := range                       -> true if n in range
701
///             | '%' number '=' range        -> true if n % number in range
702
/// range      := number
703
///             | '[' number ',' number ']'   -> ranges are inclusive both ends
704
///
705
/// Here are some examples from the GNU gettext manual written in this form:
706
/// English:
707
/// {1:form0|:form1}
708
/// Latvian:
709
/// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0}
710
/// Gaeilge:
711
/// {1:form0|2:form1|:form2}
712
/// Romanian:
713
/// {1:form0|0,%100=[1,19]:form1|:form2}
714
/// Lithuanian:
715
/// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1}
716
/// Russian (requires repeated form):
717
/// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2}
718
/// Slovak
719
/// {1:form0|[2,4]:form1|:form2}
720
/// Polish (requires repeated form):
721
/// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
722
static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo,
723
                                 const char *Argument, unsigned ArgumentLen,
724
2.04k
                                 SmallVectorImpl<char> &OutStr) {
725
2.04k
  const char *ArgumentEnd = Argument + ArgumentLen;
726
3.52k
  while (true) {
727
3.52k
    assert(Argument < ArgumentEnd && "Plural expression didn't match.");
728
3.52k
    const char *ExprEnd = Argument;
729
6.04k
    while (*ExprEnd != ':') {
730
2.51k
      assert(ExprEnd != ArgumentEnd && "Plural missing expression end");
731
2.51k
      ++ExprEnd;
732
2.51k
    }
733
3.52k
    if (EvalPluralExpr(ValNo, Argument, ExprEnd)) {
734
2.04k
      Argument = ExprEnd + 1;
735
2.04k
      ExprEnd = ScanFormat(Argument, ArgumentEnd, '|');
736
2.04k
737
2.04k
      // Recursively format the result of the plural clause into the
738
2.04k
      // output string.
739
2.04k
      DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr);
740
2.04k
      return;
741
2.04k
    }
742
1.47k
    Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1;
743
1.47k
  }
744
2.04k
}
745
746
/// Returns the friendly description for a token kind that will appear
747
/// without quotes in diagnostic messages. These strings may be translatable in
748
/// future.
749
285
static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) {
750
285
  switch (Kind) {
751
285
  case tok::identifier:
752
283
    return "identifier";
753
285
  default:
754
2
    return nullptr;
755
285
  }
756
285
}
757
758
/// FormatDiagnostic - Format this diagnostic into a string, substituting the
759
/// formal arguments into the %0 slots.  The result is appended onto the Str
760
/// array.
761
void Diagnostic::
762
253k
FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
763
253k
  if (!StoredDiagMessage.empty()) {
764
153
    OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end());
765
153
    return;
766
153
  }
767
253k
768
253k
  StringRef Diag =
769
253k
    getDiags()->getDiagnosticIDs()->getDescription(getID());
770
253k
771
253k
  FormatDiagnostic(Diag.begin(), Diag.end(), OutStr);
772
253k
}
773
774
void Diagnostic::
775
FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
776
396k
                 SmallVectorImpl<char> &OutStr) const {
777
396k
  // When the diagnostic string is only "%0", the entire string is being given
778
396k
  // by an outside source.  Remove unprintable characters from this string
779
396k
  // and skip all the other string processing.
780
396k
  if (DiagEnd - DiagStr == 2 &&
781
396k
      
StringRef(DiagStr, DiagEnd - DiagStr).equals("%0")17.3k
&&
782
396k
      
getArgKind(0) == DiagnosticsEngine::ak_std_string14.8k
) {
783
14.8k
    const std::string &S = getArgStdStr(0);
784
572k
    for (char c : S) {
785
572k
      if (llvm::sys::locale::isPrint(c) || 
c == '\t'348
) {
786
571k
        OutStr.push_back(c);
787
571k
      }
788
572k
    }
789
14.8k
    return;
790
14.8k
  }
791
381k
792
381k
  /// FormattedArgs - Keep track of all of the arguments formatted by
793
381k
  /// ConvertArgToString and pass them into subsequent calls to
794
381k
  /// ConvertArgToString, allowing the implementation to avoid redundancies in
795
381k
  /// obvious cases.
796
381k
  SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs;
797
381k
798
381k
  /// QualTypeVals - Pass a vector of arrays so that QualType names can be
799
381k
  /// compared to see if more information is needed to be printed.
800
381k
  SmallVector<intptr_t, 2> QualTypeVals;
801
381k
  SmallVector<char, 64> Tree;
802
381k
803
1.38M
  for (unsigned i = 0, e = getNumArgs(); i < e; 
++i1.00M
)
804
1.00M
    if (getArgKind(i) == DiagnosticsEngine::ak_qualtype)
805
186k
      QualTypeVals.push_back(getRawArg(i));
806
381k
807
1.20M
  while (DiagStr != DiagEnd) {
808
827k
    if (DiagStr[0] != '%') {
809
494k
      // Append non-%0 substrings to Str if we have one.
810
494k
      const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
811
494k
      OutStr.append(DiagStr, StrEnd);
812
494k
      DiagStr = StrEnd;
813
494k
      continue;
814
494k
    } else 
if (333k
isPunctuation(DiagStr[1])333k
) {
815
94
      OutStr.push_back(DiagStr[1]);  // %% -> %.
816
94
      DiagStr += 2;
817
94
      continue;
818
94
    }
819
333k
820
333k
    // Skip the %.
821
333k
    ++DiagStr;
822
333k
823
333k
    // This must be a placeholder for a diagnostic argument.  The format for a
824
333k
    // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0".
825
333k
    // The digit is a number from 0-9 indicating which argument this comes from.
826
333k
    // The modifier is a string of digits from the set [-a-z]+, arguments is a
827
333k
    // brace enclosed string.
828
333k
    const char *Modifier = nullptr, *Argument = nullptr;
829
333k
    unsigned ModifierLen = 0, ArgumentLen = 0;
830
333k
831
333k
    // Check to see if we have a modifier.  If so eat it.
832
333k
    if (!isDigit(DiagStr[0])) {
833
138k
      Modifier = DiagStr;
834
921k
      while (DiagStr[0] == '-' ||
835
921k
             (DiagStr[0] >= 'a' && 
DiagStr[0] <= 'z'907k
))
836
783k
        ++DiagStr;
837
138k
      ModifierLen = DiagStr-Modifier;
838
138k
839
138k
      // If we have an argument, get it next.
840
138k
      if (DiagStr[0] == '{') {
841
124k
        ++DiagStr; // Skip {.
842
124k
        Argument = DiagStr;
843
124k
844
124k
        DiagStr = ScanFormat(DiagStr, DiagEnd, '}');
845
124k
        assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!");
846
124k
        ArgumentLen = DiagStr-Argument;
847
124k
        ++DiagStr;  // Skip }.
848
124k
      }
849
138k
    }
850
333k
851
333k
    assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic");
852
333k
    unsigned ArgNo = *DiagStr++ - '0';
853
333k
854
333k
    // Only used for type diffing.
855
333k
    unsigned ArgNo2 = ArgNo;
856
333k
857
333k
    DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo);
858
333k
    if (ModifierIs(Modifier, ModifierLen, "diff")) {
859
9.47k
      assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) &&
860
9.47k
             "Invalid format for diff modifier");
861
9.47k
      ++DiagStr;  // Comma.
862
9.47k
      ArgNo2 = *DiagStr++ - '0';
863
9.47k
      DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2);
864
9.47k
      if (Kind == DiagnosticsEngine::ak_qualtype &&
865
9.47k
          
Kind2 == DiagnosticsEngine::ak_qualtype9.42k
)
866
9.40k
        Kind = DiagnosticsEngine::ak_qualtype_pair;
867
69
      else {
868
69
        // %diff only supports QualTypes.  For other kinds of arguments,
869
69
        // use the default printing.  For example, if the modifier is:
870
69
        //   "%diff{compare $ to $|other text}1,2"
871
69
        // treat it as:
872
69
        //   "compare %1 to %2"
873
69
        const char *ArgumentEnd = Argument + ArgumentLen;
874
69
        const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
875
69
        assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd &&
876
69
               "Found too many '|'s in a %diff modifier!");
877
69
        const char *FirstDollar = ScanFormat(Argument, Pipe, '$');
878
69
        const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$');
879
69
        const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) };
880
69
        const char ArgStr2[] = { '%', static_cast<char>('0' + ArgNo2) };
881
69
        FormatDiagnostic(Argument, FirstDollar, OutStr);
882
69
        FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr);
883
69
        FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
884
69
        FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr);
885
69
        FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
886
69
        continue;
887
69
      }
888
333k
    }
889
333k
890
333k
    switch (Kind) {
891
333k
    // ---- STRINGS ----
892
333k
    case DiagnosticsEngine::ak_std_string: {
893
35.0k
      const std::string &S = getArgStdStr(ArgNo);
894
35.0k
      assert(ModifierLen == 0 && "No modifiers for strings yet");
895
35.0k
      OutStr.append(S.begin(), S.end());
896
35.0k
      break;
897
333k
    }
898
333k
    case DiagnosticsEngine::ak_c_string: {
899
42.7k
      const char *S = getArgCStr(ArgNo);
900
42.7k
      assert(ModifierLen == 0 && "No modifiers for strings yet");
901
42.7k
902
42.7k
      // Don't crash if get passed a null pointer by accident.
903
42.7k
      if (!S)
904
0
        S = "(null)";
905
42.7k
906
42.7k
      OutStr.append(S, S + strlen(S));
907
42.7k
      break;
908
333k
    }
909
333k
    // ---- INTEGERS ----
910
333k
    case DiagnosticsEngine::ak_sint: {
911
68.4k
      int Val = getArgSInt(ArgNo);
912
68.4k
913
68.4k
      if (ModifierIs(Modifier, ModifierLen, "select")) {
914
66.3k
        HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen,
915
66.3k
                             OutStr);
916
66.3k
      } else 
if (2.09k
ModifierIs(Modifier, ModifierLen, "s")2.09k
) {
917
37
        HandleIntegerSModifier(Val, OutStr);
918
2.05k
      } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
919
462
        HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
920
462
                             OutStr);
921
1.59k
      } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
922
38
        HandleOrdinalModifier((unsigned)Val, OutStr);
923
1.55k
      } else {
924
1.55k
        assert(ModifierLen == 0 && "Unknown integer modifier");
925
1.55k
        llvm::raw_svector_ostream(OutStr) << Val;
926
1.55k
      }
927
68.4k
      break;
928
333k
    }
929
333k
    case DiagnosticsEngine::ak_uint: {
930
60.3k
      unsigned Val = getArgUInt(ArgNo);
931
60.3k
932
60.3k
      if (ModifierIs(Modifier, ModifierLen, "select")) {
933
46.7k
        HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr);
934
46.7k
      } else 
if (13.5k
ModifierIs(Modifier, ModifierLen, "s")13.5k
) {
935
1.24k
        HandleIntegerSModifier(Val, OutStr);
936
12.3k
      } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
937
1.58k
        HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
938
1.58k
                             OutStr);
939
10.7k
      } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
940
5.35k
        HandleOrdinalModifier(Val, OutStr);
941
5.38k
      } else {
942
5.38k
        assert(ModifierLen == 0 && "Unknown integer modifier");
943
5.38k
        llvm::raw_svector_ostream(OutStr) << Val;
944
5.38k
      }
945
60.3k
      break;
946
333k
    }
947
333k
    // ---- TOKEN SPELLINGS ----
948
333k
    case DiagnosticsEngine::ak_tokenkind: {
949
22.1k
      tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo));
950
22.1k
      assert(ModifierLen == 0 && "No modifiers for token kinds yet");
951
22.1k
952
22.1k
      llvm::raw_svector_ostream Out(OutStr);
953
22.1k
      if (const char *S = tok::getPunctuatorSpelling(Kind))
954
21.8k
        // Quoted token spelling for punctuators.
955
21.8k
        Out << '\'' << S << '\'';
956
305
      else if (const char *S = tok::getKeywordSpelling(Kind))
957
20
        // Unquoted token spelling for keywords.
958
20
        Out << S;
959
285
      else if (const char *S = getTokenDescForDiagnostic(Kind))
960
283
        // Unquoted translatable token name.
961
283
        Out << S;
962
2
      else if (const char *S = tok::getTokenName(Kind))
963
2
        // Debug name, shouldn't appear in user-facing diagnostics.
964
2
        Out << '<' << S << '>';
965
0
      else
966
0
        Out << "(null)";
967
22.1k
      break;
968
333k
    }
969
333k
    // ---- NAMES and TYPES ----
970
333k
    case DiagnosticsEngine::ak_identifierinfo: {
971
9.30k
      const IdentifierInfo *II = getArgIdentifier(ArgNo);
972
9.30k
      assert(ModifierLen == 0 && "No modifiers for strings yet");
973
9.30k
974
9.30k
      // Don't crash if get passed a null pointer by accident.
975
9.30k
      if (!II) {
976
8
        const char *S = "(null)";
977
8
        OutStr.append(S, S + strlen(S));
978
8
        continue;
979
8
      }
980
9.29k
981
9.29k
      llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
982
9.29k
      break;
983
9.29k
    }
984
85.5k
    case DiagnosticsEngine::ak_qual:
985
85.5k
    case DiagnosticsEngine::ak_qualtype:
986
85.5k
    case DiagnosticsEngine::ak_declarationname:
987
85.5k
    case DiagnosticsEngine::ak_nameddecl:
988
85.5k
    case DiagnosticsEngine::ak_nestednamespec:
989
85.5k
    case DiagnosticsEngine::ak_declcontext:
990
85.5k
    case DiagnosticsEngine::ak_attr:
991
85.5k
      getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
992
85.5k
                                     StringRef(Modifier, ModifierLen),
993
85.5k
                                     StringRef(Argument, ArgumentLen),
994
85.5k
                                     FormattedArgs,
995
85.5k
                                     OutStr, QualTypeVals);
996
85.5k
      break;
997
85.5k
    case DiagnosticsEngine::ak_qualtype_pair: {
998
9.40k
      // Create a struct with all the info needed for printing.
999
9.40k
      TemplateDiffTypes TDT;
1000
9.40k
      TDT.FromType = getRawArg(ArgNo);
1001
9.40k
      TDT.ToType = getRawArg(ArgNo2);
1002
9.40k
      TDT.ElideType = getDiags()->ElideType;
1003
9.40k
      TDT.ShowColors = getDiags()->ShowColors;
1004
9.40k
      TDT.TemplateDiffUsed = false;
1005
9.40k
      intptr_t val = reinterpret_cast<intptr_t>(&TDT);
1006
9.40k
1007
9.40k
      const char *ArgumentEnd = Argument + ArgumentLen;
1008
9.40k
      const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
1009
9.40k
1010
9.40k
      // Print the tree.  If this diagnostic already has a tree, skip the
1011
9.40k
      // second tree.
1012
9.40k
      if (getDiags()->PrintTemplateTree && 
Tree.empty()577
) {
1013
577
        TDT.PrintFromType = true;
1014
577
        TDT.PrintTree = true;
1015
577
        getDiags()->ConvertArgToString(Kind, val,
1016
577
                                       StringRef(Modifier, ModifierLen),
1017
577
                                       StringRef(Argument, ArgumentLen),
1018
577
                                       FormattedArgs,
1019
577
                                       Tree, QualTypeVals);
1020
577
        // If there is no tree information, fall back to regular printing.
1021
577
        if (!Tree.empty()) {
1022
347
          FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr);
1023
347
          break;
1024
347
        }
1025
9.06k
      }
1026
9.06k
1027
9.06k
      // Non-tree printing, also the fall-back when tree printing fails.
1028
9.06k
      // The fall-back is triggered when the types compared are not templates.
1029
9.06k
      const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$');
1030
9.06k
      const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$');
1031
9.06k
1032
9.06k
      // Append before text
1033
9.06k
      FormatDiagnostic(Argument, FirstDollar, OutStr);
1034
9.06k
1035
9.06k
      // Append first type
1036
9.06k
      TDT.PrintTree = false;
1037
9.06k
      TDT.PrintFromType = true;
1038
9.06k
      getDiags()->ConvertArgToString(Kind, val,
1039
9.06k
                                     StringRef(Modifier, ModifierLen),
1040
9.06k
                                     StringRef(Argument, ArgumentLen),
1041
9.06k
                                     FormattedArgs,
1042
9.06k
                                     OutStr, QualTypeVals);
1043
9.06k
      if (!TDT.TemplateDiffUsed)
1044
8.65k
        FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
1045
8.65k
                                               TDT.FromType));
1046
9.06k
1047
9.06k
      // Append middle text
1048
9.06k
      FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
1049
9.06k
1050
9.06k
      // Append second type
1051
9.06k
      TDT.PrintFromType = false;
1052
9.06k
      getDiags()->ConvertArgToString(Kind, val,
1053
9.06k
                                     StringRef(Modifier, ModifierLen),
1054
9.06k
                                     StringRef(Argument, ArgumentLen),
1055
9.06k
                                     FormattedArgs,
1056
9.06k
                                     OutStr, QualTypeVals);
1057
9.06k
      if (!TDT.TemplateDiffUsed)
1058
8.65k
        FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
1059
8.65k
                                               TDT.ToType));
1060
9.06k
1061
9.06k
      // Append end text
1062
9.06k
      FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
1063
9.06k
      break;
1064
9.06k
    }
1065
333k
    }
1066
333k
1067
333k
    // Remember this argument info for subsequent formatting operations.  Turn
1068
333k
    // std::strings into a null terminated string to make it be the same case as
1069
333k
    // all the other ones.
1070
333k
    if (Kind == DiagnosticsEngine::ak_qualtype_pair)
1071
9.40k
      continue;
1072
323k
    else if (Kind != DiagnosticsEngine::ak_std_string)
1073
288k
      FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo)));
1074
35.0k
    else
1075
35.0k
      FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string,
1076
35.0k
                                        (intptr_t)getArgStdStr(ArgNo).c_str()));
1077
333k
  }
1078
381k
1079
381k
  // Append the type tree to the end of the diagnostics.
1080
381k
  OutStr.append(Tree.begin(), Tree.end());
1081
381k
}
1082
1083
StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1084
                                   StringRef Message)
1085
0
    : ID(ID), Level(Level), Message(Message) {}
1086
1087
StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level,
1088
                                   const Diagnostic &Info)
1089
10.4k
    : ID(Info.getID()), Level(Level) {
1090
10.4k
  assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) &&
1091
10.4k
       "Valid source location without setting a source manager for diagnostic");
1092
10.4k
  if (Info.getLocation().isValid())
1093
10.4k
    Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
1094
10.4k
  SmallString<64> Message;
1095
10.4k
  Info.FormatDiagnostic(Message);
1096
10.4k
  this->Message.assign(Message.begin(), Message.end());
1097
10.4k
  this->Ranges.assign(Info.getRanges().begin(), Info.getRanges().end());
1098
10.4k
  this->FixIts.assign(Info.getFixItHints().begin(), Info.getFixItHints().end());
1099
10.4k
}
1100
1101
StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1102
                                   StringRef Message, FullSourceLoc Loc,
1103
                                   ArrayRef<CharSourceRange> Ranges,
1104
                                   ArrayRef<FixItHint> FixIts)
1105
    : ID(ID), Level(Level), Loc(Loc), Message(Message),
1106
      Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end())
1107
65
{
1108
65
}
1109
1110
/// IncludeInDiagnosticCounts - This method (whose default implementation
1111
///  returns true) indicates whether the diagnostics handled by this
1112
///  DiagnosticConsumer should be included in the number of diagnostics
1113
///  reported by DiagnosticsEngine.
1114
622k
bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; }
1115
1116
0
void IgnoringDiagConsumer::anchor() {}
1117
1118
1.33k
ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() = default;
1119
1120
void ForwardingDiagnosticConsumer::HandleDiagnostic(
1121
       DiagnosticsEngine::Level DiagLevel,
1122
544
       const Diagnostic &Info) {
1123
544
  Target.HandleDiagnostic(DiagLevel, Info);
1124
544
}
1125
1126
0
void ForwardingDiagnosticConsumer::clear() {
1127
0
  DiagnosticConsumer::clear();
1128
0
  Target.clear();
1129
0
}
1130
1131
590
bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const {
1132
590
  return Target.IncludeInDiagnosticCounts();
1133
590
}
1134
1135
41.7k
PartialDiagnostic::StorageAllocator::StorageAllocator() {
1136
709k
  for (unsigned I = 0; I != NumCached; 
++I667k
)
1137
667k
    FreeList[I] = Cached + I;
1138
41.7k
  NumFreeListEntries = NumCached;
1139
41.7k
}
1140
1141
33.1k
PartialDiagnostic::StorageAllocator::~StorageAllocator() {
1142
33.1k
  // Don't assert if we are in a CrashRecovery context, as this invariant may
1143
33.1k
  // be invalidated during a crash.
1144
33.1k
  assert((NumFreeListEntries == NumCached ||
1145
33.1k
          llvm::CrashRecoveryContext::isRecoveringFromCrash()) &&
1146
33.1k
         "A partial is on the lam");
1147
33.1k
}
1148
1149
char DiagnosticError::ID;