Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Basic/Diagnostic.h
Line
Count
Source (jump to first uncovered line)
1
//===- Diagnostic.h - C Language Family Diagnostic Handling -----*- C++ -*-===//
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
/// \file
10
/// Defines the Diagnostic-related interfaces.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_H
15
#define LLVM_CLANG_BASIC_DIAGNOSTIC_H
16
17
#include "clang/Basic/DiagnosticIDs.h"
18
#include "clang/Basic/DiagnosticOptions.h"
19
#include "clang/Basic/SourceLocation.h"
20
#include "clang/Basic/Specifiers.h"
21
#include "llvm/ADT/ArrayRef.h"
22
#include "llvm/ADT/DenseMap.h"
23
#include "llvm/ADT/IntrusiveRefCntPtr.h"
24
#include "llvm/ADT/SmallVector.h"
25
#include "llvm/ADT/StringRef.h"
26
#include "llvm/ADT/iterator_range.h"
27
#include "llvm/Support/Compiler.h"
28
#include "llvm/Support/Error.h"
29
#include <cassert>
30
#include <cstdint>
31
#include <limits>
32
#include <list>
33
#include <map>
34
#include <memory>
35
#include <string>
36
#include <type_traits>
37
#include <utility>
38
#include <vector>
39
40
namespace clang {
41
42
class DeclContext;
43
class DiagnosticBuilder;
44
class DiagnosticConsumer;
45
class IdentifierInfo;
46
class LangOptions;
47
class Preprocessor;
48
class SourceManager;
49
class StoredDiagnostic;
50
51
namespace tok {
52
53
enum TokenKind : unsigned short;
54
55
} // namespace tok
56
57
/// Annotates a diagnostic with some code that should be
58
/// inserted, removed, or replaced to fix the problem.
59
///
60
/// This kind of hint should be used when we are certain that the
61
/// introduction, removal, or modification of a particular (small!)
62
/// amount of code will correct a compilation error. The compiler
63
/// should also provide full recovery from such errors, such that
64
/// suppressing the diagnostic output can still result in successful
65
/// compilation.
66
class FixItHint {
67
public:
68
  /// Code that should be replaced to correct the error. Empty for an
69
  /// insertion hint.
70
  CharSourceRange RemoveRange;
71
72
  /// Code in the specific range that should be inserted in the insertion
73
  /// location.
74
  CharSourceRange InsertFromRange;
75
76
  /// The actual code to insert at the insertion location, as a
77
  /// string.
78
  std::string CodeToInsert;
79
80
  bool BeforePreviousInsertions = false;
81
82
  /// Empty code modification hint, indicating that no code
83
  /// modification is known.
84
7.21M
  FixItHint() = default;
85
86
275k
  bool isNull() const {
87
275k
    return !RemoveRange.isValid();
88
275k
  }
89
90
  /// Create a code modification hint that inserts the given
91
  /// code string at a specific location.
92
  static FixItHint CreateInsertion(SourceLocation InsertionLoc,
93
                                   StringRef Code,
94
148k
                                   bool BeforePreviousInsertions = false) {
95
148k
    FixItHint Hint;
96
148k
    Hint.RemoveRange =
97
148k
      CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
98
148k
    Hint.CodeToInsert = Code;
99
148k
    Hint.BeforePreviousInsertions = BeforePreviousInsertions;
100
148k
    return Hint;
101
148k
  }
102
103
  /// Create a code modification hint that inserts the given
104
  /// code from \p FromRange at a specific location.
105
  static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
106
                                            CharSourceRange FromRange,
107
115
                                        bool BeforePreviousInsertions = false) {
108
115
    FixItHint Hint;
109
115
    Hint.RemoveRange =
110
115
      CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
111
115
    Hint.InsertFromRange = FromRange;
112
115
    Hint.BeforePreviousInsertions = BeforePreviousInsertions;
113
115
    return Hint;
114
115
  }
115
116
  /// Create a code modification hint that removes the given
117
  /// source range.
118
35.8k
  static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
119
35.8k
    FixItHint Hint;
120
35.8k
    Hint.RemoveRange = RemoveRange;
121
35.8k
    return Hint;
122
35.8k
  }
123
35.3k
  static FixItHint CreateRemoval(SourceRange RemoveRange) {
124
35.3k
    return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
125
35.3k
  }
126
127
  /// Create a code modification hint that replaces the given
128
  /// source range with the given code string.
129
  static FixItHint CreateReplacement(CharSourceRange RemoveRange,
130
32.3k
                                     StringRef Code) {
131
32.3k
    FixItHint Hint;
132
32.3k
    Hint.RemoveRange = RemoveRange;
133
32.3k
    Hint.CodeToInsert = Code;
134
32.3k
    return Hint;
135
32.3k
  }
136
137
  static FixItHint CreateReplacement(SourceRange RemoveRange,
138
10.8k
                                     StringRef Code) {
139
10.8k
    return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
140
10.8k
  }
141
};
142
143
/// Concrete class used by the front-end to report problems and issues.
144
///
145
/// This massages the diagnostics (e.g. handling things like "report warnings
146
/// as errors" and passes them off to the DiagnosticConsumer for reporting to
147
/// the user. DiagnosticsEngine is tied to one translation unit and one
148
/// SourceManager.
149
class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
150
public:
151
  /// The level of the diagnostic, after it has been through mapping.
152
  enum Level {
153
    Ignored = DiagnosticIDs::Ignored,
154
    Note = DiagnosticIDs::Note,
155
    Remark = DiagnosticIDs::Remark,
156
    Warning = DiagnosticIDs::Warning,
157
    Error = DiagnosticIDs::Error,
158
    Fatal = DiagnosticIDs::Fatal
159
  };
160
161
  enum ArgumentKind {
162
    /// std::string
163
    ak_std_string,
164
165
    /// const char *
166
    ak_c_string,
167
168
    /// int
169
    ak_sint,
170
171
    /// unsigned
172
    ak_uint,
173
174
    /// enum TokenKind : unsigned
175
    ak_tokenkind,
176
177
    /// IdentifierInfo
178
    ak_identifierinfo,
179
180
    /// Qualifiers
181
    ak_qual,
182
183
    /// QualType
184
    ak_qualtype,
185
186
    /// DeclarationName
187
    ak_declarationname,
188
189
    /// NamedDecl *
190
    ak_nameddecl,
191
192
    /// NestedNameSpecifier *
193
    ak_nestednamespec,
194
195
    /// DeclContext *
196
    ak_declcontext,
197
198
    /// pair<QualType, QualType>
199
    ak_qualtype_pair,
200
201
    /// Attr *
202
    ak_attr
203
  };
204
205
  /// Represents on argument value, which is a union discriminated
206
  /// by ArgumentKind, with a value.
207
  using ArgumentValue = std::pair<ArgumentKind, intptr_t>;
208
209
private:
210
  // Used by __extension__
211
  unsigned char AllExtensionsSilenced = 0;
212
213
  // Treat fatal errors like errors.
214
  bool FatalsAsError = false;
215
216
  // Suppress all diagnostics.
217
  bool SuppressAllDiagnostics = false;
218
219
  // Elide common types of templates.
220
  bool ElideType = true;
221
222
  // Print a tree when comparing templates.
223
  bool PrintTemplateTree = false;
224
225
  // Color printing is enabled.
226
  bool ShowColors = false;
227
228
  // Which overload candidates to show.
229
  OverloadsShown ShowOverloads = Ovl_All;
230
231
  // Cap of # errors emitted, 0 -> no limit.
232
  unsigned ErrorLimit = 0;
233
234
  // Cap on depth of template backtrace stack, 0 -> no limit.
235
  unsigned TemplateBacktraceLimit = 0;
236
237
  // Cap on depth of constexpr evaluation backtrace stack, 0 -> no limit.
238
  unsigned ConstexprBacktraceLimit = 0;
239
240
  IntrusiveRefCntPtr<DiagnosticIDs> Diags;
241
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
242
  DiagnosticConsumer *Client = nullptr;
243
  std::unique_ptr<DiagnosticConsumer> Owner;
244
  SourceManager *SourceMgr = nullptr;
245
246
  /// Mapping information for diagnostics.
247
  ///
248
  /// Mapping info is packed into four bits per diagnostic.  The low three
249
  /// bits are the mapping (an instance of diag::Severity), or zero if unset.
250
  /// The high bit is set when the mapping was established as a user mapping.
251
  /// If the high bit is clear, then the low bits are set to the default
252
  /// value, and should be mapped with -pedantic, -Werror, etc.
253
  ///
254
  /// A new DiagState is created and kept around when diagnostic pragmas modify
255
  /// the state so that we know what is the diagnostic state at any given
256
  /// source location.
257
  class DiagState {
258
    llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
259
260
  public:
261
    // "Global" configuration state that can actually vary between modules.
262
263
    // Ignore all warnings: -w
264
    unsigned IgnoreAllWarnings : 1;
265
266
    // Enable all warnings.
267
    unsigned EnableAllWarnings : 1;
268
269
    // Treat warnings like errors.
270
    unsigned WarningsAsErrors : 1;
271
272
    // Treat errors like fatal errors.
273
    unsigned ErrorsAsFatal : 1;
274
275
    // Suppress warnings in system headers.
276
    unsigned SuppressSystemWarnings : 1;
277
278
    // Map extensions to warnings or errors?
279
    diag::Severity ExtBehavior = diag::Severity::Ignored;
280
281
    DiagState()
282
        : IgnoreAllWarnings(false), EnableAllWarnings(false),
283
          WarningsAsErrors(false), ErrorsAsFatal(false),
284
169k
          SuppressSystemWarnings(false) {}
285
286
    using iterator = llvm::DenseMap<unsigned, DiagnosticMapping>::iterator;
287
    using const_iterator =
288
        llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator;
289
290
2.16M
    void setMapping(diag::kind Diag, DiagnosticMapping Info) {
291
2.16M
      DiagMap[Diag] = Info;
292
2.16M
    }
293
294
0
    DiagnosticMapping lookupMapping(diag::kind Diag) const {
295
0
      return DiagMap.lookup(Diag);
296
0
    }
297
298
    DiagnosticMapping &getOrAddMapping(diag::kind Diag);
299
300
6.72k
    const_iterator begin() const { return DiagMap.begin(); }
301
6.72k
    const_iterator end() const { return DiagMap.end(); }
302
  };
303
304
  /// Keeps and automatically disposes all DiagStates that we create.
305
  std::list<DiagState> DiagStates;
306
307
  /// A mapping from files to the diagnostic states for those files. Lazily
308
  /// built on demand for files in which the diagnostic state has not changed.
309
  class DiagStateMap {
310
  public:
311
    /// Add an initial diagnostic state.
312
    void appendFirst(DiagState *State);
313
314
    /// Add a new latest state point.
315
    void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
316
317
    /// Look up the diagnostic state at a given source location.
318
    DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
319
320
    /// Determine whether this map is empty.
321
0
    bool empty() const { return Files.empty(); }
322
323
    /// Clear out this map.
324
168k
    void clear() {
325
168k
      Files.clear();
326
168k
      FirstDiagState = CurDiagState = nullptr;
327
168k
      CurDiagStateLoc = SourceLocation();
328
168k
    }
329
330
    /// Produce a debugging dump of the diagnostic state.
331
    LLVM_DUMP_METHOD void dump(SourceManager &SrcMgr,
332
                               StringRef DiagName = StringRef()) const;
333
334
    /// Grab the most-recently-added state point.
335
14.8M
    DiagState *getCurDiagState() const { return CurDiagState; }
336
337
    /// Get the location at which a diagnostic state was last added.
338
45.2k
    SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
339
340
  private:
341
    friend class ASTReader;
342
    friend class ASTWriter;
343
344
    /// Represents a point in source where the diagnostic state was
345
    /// modified because of a pragma.
346
    ///
347
    /// 'Loc' can be null if the point represents the diagnostic state
348
    /// modifications done through the command-line.
349
    struct DiagStatePoint {
350
      DiagState *State;
351
      unsigned Offset;
352
353
      DiagStatePoint(DiagState *State, unsigned Offset)
354
88.8k
          : State(State), Offset(Offset) {}
355
    };
356
357
    /// Description of the diagnostic states and state transitions for a
358
    /// particular FileID.
359
    struct File {
360
      /// The diagnostic state for the parent file. This is strictly redundant,
361
      /// as looking up the DecomposedIncludedLoc for the FileID in the Files
362
      /// map would give us this, but we cache it here for performance.
363
      File *Parent = nullptr;
364
365
      /// The offset of this file within its parent.
366
      unsigned ParentOffset = 0;
367
368
      /// Whether this file has any local (not imported from an AST file)
369
      /// diagnostic state transitions.
370
      bool HasLocalTransitions = false;
371
372
      /// The points within the file where the state changes. There will always
373
      /// be at least one of these (the state on entry to the file).
374
      llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
375
376
      DiagState *lookup(unsigned Offset) const;
377
    };
378
379
    /// The diagnostic states for each file.
380
    mutable std::map<FileID, File> Files;
381
382
    /// The initial diagnostic state.
383
    DiagState *FirstDiagState;
384
385
    /// The current diagnostic state.
386
    DiagState *CurDiagState;
387
388
    /// The location at which the current diagnostic state was established.
389
    SourceLocation CurDiagStateLoc;
390
391
    /// Get the diagnostic state information for a file.
392
    File *getFile(SourceManager &SrcMgr, FileID ID) const;
393
  };
394
395
  DiagStateMap DiagStatesByLoc;
396
397
  /// Keeps the DiagState that was active during each diagnostic 'push'
398
  /// so we can get back at it when we 'pop'.
399
  std::vector<DiagState *> DiagStateOnPushStack;
400
401
10.4M
  DiagState *GetCurDiagState() const {
402
10.4M
    return DiagStatesByLoc.getCurDiagState();
403
10.4M
  }
404
405
  void PushDiagStatePoint(DiagState *State, SourceLocation L);
406
407
  /// Finds the DiagStatePoint that contains the diagnostic state of
408
  /// the given source location.
409
99.6M
  DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
410
99.6M
    return SourceMgr ? 
DiagStatesByLoc.lookup(*SourceMgr, Loc)99.6M
411
99.6M
                     : 
DiagStatesByLoc.getCurDiagState()44.5k
;
412
99.6M
  }
413
414
  /// Sticky flag set to \c true when an error is emitted.
415
  bool ErrorOccurred;
416
417
  /// Sticky flag set to \c true when an "uncompilable error" occurs.
418
  /// I.e. an error that was not upgraded from a warning by -Werror.
419
  bool UncompilableErrorOccurred;
420
421
  /// Sticky flag set to \c true when a fatal error is emitted.
422
  bool FatalErrorOccurred;
423
424
  /// Indicates that an unrecoverable error has occurred.
425
  bool UnrecoverableErrorOccurred;
426
427
  /// Counts for DiagnosticErrorTrap to check whether an error occurred
428
  /// during a parsing section, e.g. during parsing a function.
429
  unsigned TrapNumErrorsOccurred;
430
  unsigned TrapNumUnrecoverableErrorsOccurred;
431
432
  /// The level of the last diagnostic emitted.
433
  ///
434
  /// This is used to emit continuation diagnostics with the same level as the
435
  /// diagnostic that they follow.
436
  DiagnosticIDs::Level LastDiagLevel;
437
438
  /// Number of warnings reported
439
  unsigned NumWarnings;
440
441
  /// Number of errors reported
442
  unsigned NumErrors;
443
444
  /// A function pointer that converts an opaque diagnostic
445
  /// argument to a strings.
446
  ///
447
  /// This takes the modifiers and argument that was present in the diagnostic.
448
  ///
449
  /// The PrevArgs array indicates the previous arguments formatted for this
450
  /// diagnostic.  Implementations of this function can use this information to
451
  /// avoid redundancy across arguments.
452
  ///
453
  /// This is a hack to avoid a layering violation between libbasic and libsema.
454
  using ArgToStringFnTy = void (*)(
455
      ArgumentKind Kind, intptr_t Val,
456
      StringRef Modifier, StringRef Argument,
457
      ArrayRef<ArgumentValue> PrevArgs,
458
      SmallVectorImpl<char> &Output,
459
      void *Cookie,
460
      ArrayRef<intptr_t> QualTypeVals);
461
462
  void *ArgToStringCookie = nullptr;
463
  ArgToStringFnTy ArgToStringFn;
464
465
  /// ID of the "delayed" diagnostic, which is a (typically
466
  /// fatal) diagnostic that had to be delayed because it was found
467
  /// while emitting another diagnostic.
468
  unsigned DelayedDiagID;
469
470
  /// First string argument for the delayed diagnostic.
471
  std::string DelayedDiagArg1;
472
473
  /// Second string argument for the delayed diagnostic.
474
  std::string DelayedDiagArg2;
475
476
  /// Optional flag value.
477
  ///
478
  /// Some flags accept values, for instance: -Wframe-larger-than=<value> and
479
  /// -Rpass=<value>. The content of this string is emitted after the flag name
480
  /// and '='.
481
  std::string FlagValue;
482
483
public:
484
  explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
485
                             IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
486
                             DiagnosticConsumer *client = nullptr,
487
                             bool ShouldOwnClient = true);
488
  DiagnosticsEngine(const DiagnosticsEngine &) = delete;
489
  DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
490
  ~DiagnosticsEngine();
491
492
  LLVM_DUMP_METHOD void dump() const;
493
  LLVM_DUMP_METHOD void dump(StringRef DiagName) const;
494
495
336k
  const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
496
336k
    return Diags;
497
336k
  }
498
499
  /// Retrieve the diagnostic options.
500
1.16M
  DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
501
502
  using diag_mapping_range = llvm::iterator_range<DiagState::const_iterator>;
503
504
  /// Get the current set of diagnostic mappings.
505
3.01k
  diag_mapping_range getDiagnosticMappings() const {
506
3.01k
    const DiagState &DS = *GetCurDiagState();
507
3.01k
    return diag_mapping_range(DS.begin(), DS.end());
508
3.01k
  }
509
510
332k
  DiagnosticConsumer *getClient() { return Client; }
511
0
  const DiagnosticConsumer *getClient() const { return Client; }
512
513
  /// Determine whether this \c DiagnosticsEngine object own its client.
514
29
  bool ownsClient() const { return Owner != nullptr; }
515
516
  /// Return the current diagnostic client along with ownership of that
517
  /// client.
518
37.9k
  std::unique_ptr<DiagnosticConsumer> takeClient() { return std::move(Owner); }
519
520
235k
  bool hasSourceManager() const { return SourceMgr != nullptr; }
521
522
23.1M
  SourceManager &getSourceManager() const {
523
23.1M
    assert(SourceMgr && "SourceManager not set!");
524
23.1M
    return *SourceMgr;
525
23.1M
  }
526
527
92.3k
  void setSourceManager(SourceManager *SrcMgr) {
528
92.3k
    assert(DiagStatesByLoc.empty() &&
529
92.3k
           "Leftover diag state from a different SourceManager.");
530
92.3k
    SourceMgr = SrcMgr;
531
92.3k
  }
532
533
  //===--------------------------------------------------------------------===//
534
  //  DiagnosticsEngine characterization methods, used by a client to customize
535
  //  how diagnostics are emitted.
536
  //
537
538
  /// Copies the current DiagMappings and pushes the new copy
539
  /// onto the top of the stack.
540
  void pushMappings(SourceLocation Loc);
541
542
  /// Pops the current DiagMappings off the top of the stack,
543
  /// causing the new top of the stack to be the active mappings.
544
  ///
545
  /// \returns \c true if the pop happens, \c false if there is only one
546
  /// DiagMapping on the stack.
547
  bool popMappings(SourceLocation Loc);
548
549
  /// Set the diagnostic client associated with this diagnostic object.
550
  ///
551
  /// \param ShouldOwnClient true if the diagnostic object should take
552
  /// ownership of \c client.
553
  void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
554
555
  /// Specify a limit for the number of errors we should
556
  /// emit before giving up.
557
  ///
558
  /// Zero disables the limit.
559
28.5k
  void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
560
561
  /// Specify the maximum number of template instantiation
562
  /// notes to emit along with a given diagnostic.
563
79.0k
  void setTemplateBacktraceLimit(unsigned Limit) {
564
79.0k
    TemplateBacktraceLimit = Limit;
565
79.0k
  }
566
567
  /// Retrieve the maximum number of template instantiation
568
  /// notes to emit along with a given diagnostic.
569
4.13k
  unsigned getTemplateBacktraceLimit() const {
570
4.13k
    return TemplateBacktraceLimit;
571
4.13k
  }
572
573
  /// Specify the maximum number of constexpr evaluation
574
  /// notes to emit along with a given diagnostic.
575
79.0k
  void setConstexprBacktraceLimit(unsigned Limit) {
576
79.0k
    ConstexprBacktraceLimit = Limit;
577
79.0k
  }
578
579
  /// Retrieve the maximum number of constexpr evaluation
580
  /// notes to emit along with a given diagnostic.
581
954k
  unsigned getConstexprBacktraceLimit() const {
582
954k
    return ConstexprBacktraceLimit;
583
954k
  }
584
585
  /// When set to true, any unmapped warnings are ignored.
586
  ///
587
  /// If this and WarningsAsErrors are both set, then this one wins.
588
109k
  void setIgnoreAllWarnings(bool Val) {
589
109k
    GetCurDiagState()->IgnoreAllWarnings = Val;
590
109k
  }
591
3.02M
  bool getIgnoreAllWarnings() const {
592
3.02M
    return GetCurDiagState()->IgnoreAllWarnings;
593
3.02M
  }
594
595
  /// When set to true, any unmapped ignored warnings are no longer
596
  /// ignored.
597
  ///
598
  /// If this and IgnoreAllWarnings are both set, then that one wins.
599
41
  void setEnableAllWarnings(bool Val) {
600
41
    GetCurDiagState()->EnableAllWarnings = Val;
601
41
  }
602
38
  bool getEnableAllWarnings() const {
603
38
    return GetCurDiagState()->EnableAllWarnings;
604
38
  }
605
606
  /// When set to true, any warnings reported are issued as errors.
607
1.64k
  void setWarningsAsErrors(bool Val) {
608
1.64k
    GetCurDiagState()->WarningsAsErrors = Val;
609
1.64k
  }
610
3.07k
  bool getWarningsAsErrors() const {
611
3.07k
    return GetCurDiagState()->WarningsAsErrors;
612
3.07k
  }
613
614
  /// When set to true, any error reported is made a fatal error.
615
2
  void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = Val; }
616
0
  bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; }
617
618
  /// \brief When set to true, any fatal error reported is made an error.
619
  ///
620
  /// This setting takes precedence over the setErrorsAsFatal setting above.
621
  void setFatalsAsError(bool Val) { FatalsAsError = Val; }
622
0
  bool getFatalsAsError() const { return FatalsAsError; }
623
624
  /// When set to true mask warnings that come from system headers.
625
79.1k
  void setSuppressSystemWarnings(bool Val) {
626
79.1k
    GetCurDiagState()->SuppressSystemWarnings = Val;
627
79.1k
  }
628
5.33M
  bool getSuppressSystemWarnings() const {
629
5.33M
    return GetCurDiagState()->SuppressSystemWarnings;
630
5.33M
  }
631
632
  /// Suppress all diagnostics, to silence the front end when we
633
  /// know that we don't want any more diagnostics to be passed along to the
634
  /// client
635
121k
  void setSuppressAllDiagnostics(bool Val = true) {
636
121k
    SuppressAllDiagnostics = Val;
637
121k
  }
638
3.54M
  bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
639
640
  /// Set type eliding, to skip outputting same types occurring in
641
  /// template types.
642
79.0k
  void setElideType(bool Val = true) { ElideType = Val; }
643
0
  bool getElideType() { return ElideType; }
644
645
  /// Set tree printing, to outputting the template difference in a
646
  /// tree format.
647
79.0k
  void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; }
648
0
  bool getPrintTemplateTree() { return PrintTemplateTree; }
649
650
  /// Set color printing, so the type diffing will inject color markers
651
  /// into the output.
652
79.0k
  void setShowColors(bool Val = false) { ShowColors = Val; }
653
943
  bool getShowColors() { return ShowColors; }
654
655
  /// Specify which overload candidates to show when overload resolution
656
  /// fails.
657
  ///
658
  /// By default, we show all candidates.
659
79.0k
  void setShowOverloads(OverloadsShown Val) {
660
79.0k
    ShowOverloads = Val;
661
79.0k
  }
662
5.90k
  OverloadsShown getShowOverloads() const { return ShowOverloads; }
663
664
  /// Pretend that the last diagnostic issued was ignored, so any
665
  /// subsequent notes will be suppressed, or restore a prior ignoring
666
  /// state after ignoring some diagnostics and their notes, possibly in
667
  /// the middle of another diagnostic.
668
  ///
669
  /// This can be used by clients who suppress diagnostics themselves.
670
2.79M
  void setLastDiagnosticIgnored(bool Ignored = true) {
671
2.79M
    if (LastDiagLevel == DiagnosticIDs::Fatal)
672
4
      FatalErrorOccurred = true;
673
2.79M
    LastDiagLevel = Ignored ? 
DiagnosticIDs::Ignored2.77M
:
DiagnosticIDs::Warning16.4k
;
674
2.79M
  }
675
676
  /// Determine whether the previous diagnostic was ignored. This can
677
  /// be used by clients that want to determine whether notes attached to a
678
  /// diagnostic will be suppressed.
679
2.63M
  bool isLastDiagnosticIgnored() const {
680
2.63M
    return LastDiagLevel == DiagnosticIDs::Ignored;
681
2.63M
  }
682
683
  /// Controls whether otherwise-unmapped extension diagnostics are
684
  /// mapped onto ignore/warning/error.
685
  ///
686
  /// This corresponds to the GCC -pedantic and -pedantic-errors option.
687
79.0k
  void setExtensionHandlingBehavior(diag::Severity H) {
688
79.0k
    GetCurDiagState()->ExtBehavior = H;
689
79.0k
  }
690
4.56k
  diag::Severity getExtensionHandlingBehavior() const {
691
4.56k
    return GetCurDiagState()->ExtBehavior;
692
4.56k
  }
693
694
  /// Counter bumped when an __extension__  block is/ encountered.
695
  ///
696
  /// When non-zero, all extension diagnostics are entirely silenced, no
697
  /// matter how they are mapped.
698
24.4k
  void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
699
24.4k
  void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
700
37.1M
  bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
701
702
  /// This allows the client to specify that certain warnings are
703
  /// ignored.
704
  ///
705
  /// Notes can never be mapped, errors can only be mapped to fatal, and
706
  /// WARNINGs and EXTENSIONs can be mapped arbitrarily.
707
  ///
708
  /// \param Loc The source location that this change of diagnostic state should
709
  /// take affect. It can be null if we are setting the latest state.
710
  void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
711
712
  /// Change an entire diagnostic group (e.g. "unknown-pragmas") to
713
  /// have the specified mapping.
714
  ///
715
  /// \returns true (and ignores the request) if "Group" was unknown, false
716
  /// otherwise.
717
  ///
718
  /// \param Flavor The flavor of group to affect. -Rfoo does not affect the
719
  /// state of the -Wfoo group and vice versa.
720
  ///
721
  /// \param Loc The source location that this change of diagnostic state should
722
  /// take affect. It can be null if we are setting the state from command-line.
723
  bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
724
                           diag::Severity Map,
725
                           SourceLocation Loc = SourceLocation());
726
727
  /// Set the warning-as-error flag for the given diagnostic group.
728
  ///
729
  /// This function always only operates on the current diagnostic state.
730
  ///
731
  /// \returns True if the given group is unknown, false otherwise.
732
  bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
733
734
  /// Set the error-as-fatal flag for the given diagnostic group.
735
  ///
736
  /// This function always only operates on the current diagnostic state.
737
  ///
738
  /// \returns True if the given group is unknown, false otherwise.
739
  bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
740
741
  /// Add the specified mapping to all diagnostics of the specified
742
  /// flavor.
743
  ///
744
  /// Mainly to be used by -Wno-everything to disable all warnings but allow
745
  /// subsequent -W options to enable specific warnings.
746
  void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
747
                         SourceLocation Loc = SourceLocation());
748
749
16.2M
  bool hasErrorOccurred() const { return ErrorOccurred; }
750
751
  /// Errors that actually prevent compilation, not those that are
752
  /// upgraded from a warning by -Werror.
753
3.98M
  bool hasUncompilableErrorOccurred() const {
754
3.98M
    return UncompilableErrorOccurred;
755
3.98M
  }
756
6.85M
  bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
757
758
  /// Determine whether any kind of unrecoverable error has occurred.
759
101
  bool hasUnrecoverableErrorOccurred() const {
760
101
    return FatalErrorOccurred || 
UnrecoverableErrorOccurred99
;
761
101
  }
762
763
138
  unsigned getNumWarnings() const { return NumWarnings; }
764
765
487
  void setNumWarnings(unsigned NumWarnings) {
766
487
    this->NumWarnings = NumWarnings;
767
487
  }
768
769
  /// Return an ID for a diagnostic with the specified format string and
770
  /// level.
771
  ///
772
  /// If this is the first request for this diagnostic, it is registered and
773
  /// created, otherwise the existing ID is returned.
774
  ///
775
  /// \param FormatString A fixed diagnostic format string that will be hashed
776
  /// and mapped to a unique DiagID.
777
  template <unsigned N>
778
2.69k
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
2.69k
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
2.69k
                                  StringRef(FormatString, N - 1));
781
2.69k
  }
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<73u>(clang::DiagnosticsEngine::Level, char const (&) [73u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<34u>(clang::DiagnosticsEngine::Level, char const (&) [34u])
unsigned int clang::DiagnosticsEngine::getCustomDiagID<60u>(clang::DiagnosticsEngine::Level, char const (&) [60u])
Line
Count
Source
778
2
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
2
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
2
                                  StringRef(FormatString, N - 1));
781
2
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<82u>(clang::DiagnosticsEngine::Level, char const (&) [82u])
Line
Count
Source
778
6
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
6
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
6
                                  StringRef(FormatString, N - 1));
781
6
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<141u>(clang::DiagnosticsEngine::Level, char const (&) [141u])
Line
Count
Source
778
6
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
6
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
6
                                  StringRef(FormatString, N - 1));
781
6
  }
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<62u>(clang::DiagnosticsEngine::Level, char const (&) [62u])
unsigned int clang::DiagnosticsEngine::getCustomDiagID<90u>(clang::DiagnosticsEngine::Level, char const (&) [90u])
Line
Count
Source
778
1
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
1
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
1
                                  StringRef(FormatString, N - 1));
781
1
  }
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<83u>(clang::DiagnosticsEngine::Level, char const (&) [83u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<39u>(clang::DiagnosticsEngine::Level, char const (&) [39u])
unsigned int clang::DiagnosticsEngine::getCustomDiagID<3u>(clang::DiagnosticsEngine::Level, char const (&) [3u])
Line
Count
Source
778
2.01k
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
2.01k
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
2.01k
                                  StringRef(FormatString, N - 1));
781
2.01k
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<30u>(clang::DiagnosticsEngine::Level, char const (&) [30u])
Line
Count
Source
778
1
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
1
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
1
                                  StringRef(FormatString, N - 1));
781
1
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<27u>(clang::DiagnosticsEngine::Level, char const (&) [27u])
Line
Count
Source
778
6
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
6
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
6
                                  StringRef(FormatString, N - 1));
781
6
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<95u>(clang::DiagnosticsEngine::Level, char const (&) [95u])
Line
Count
Source
778
2
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
2
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
2
                                  StringRef(FormatString, N - 1));
781
2
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<20u>(clang::DiagnosticsEngine::Level, char const (&) [20u])
Line
Count
Source
778
2
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
2
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
2
                                  StringRef(FormatString, N - 1));
781
2
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<61u>(clang::DiagnosticsEngine::Level, char const (&) [61u])
Line
Count
Source
778
164
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
164
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
164
                                  StringRef(FormatString, N - 1));
781
164
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<68u>(clang::DiagnosticsEngine::Level, char const (&) [68u])
Line
Count
Source
778
78
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
78
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
78
                                  StringRef(FormatString, N - 1));
781
78
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<113u>(clang::DiagnosticsEngine::Level, char const (&) [113u])
Line
Count
Source
778
164
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
164
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
164
                                  StringRef(FormatString, N - 1));
781
164
  }
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<26u>(clang::DiagnosticsEngine::Level, char const (&) [26u])
unsigned int clang::DiagnosticsEngine::getCustomDiagID<54u>(clang::DiagnosticsEngine::Level, char const (&) [54u])
Line
Count
Source
778
250
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
250
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
250
                                  StringRef(FormatString, N - 1));
781
250
  }
unsigned int clang::DiagnosticsEngine::getCustomDiagID<37u>(clang::DiagnosticsEngine::Level, char const (&) [37u])
Line
Count
Source
778
2
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
2
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
2
                                  StringRef(FormatString, N - 1));
781
2
  }
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<58u>(clang::DiagnosticsEngine::Level, char const (&) [58u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<38u>(clang::DiagnosticsEngine::Level, char const (&) [38u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<63u>(clang::DiagnosticsEngine::Level, char const (&) [63u])
unsigned int clang::DiagnosticsEngine::getCustomDiagID<50u>(clang::DiagnosticsEngine::Level, char const (&) [50u])
Line
Count
Source
778
2
  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
779
2
    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
780
2
                                  StringRef(FormatString, N - 1));
781
2
  }
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<46u>(clang::DiagnosticsEngine::Level, char const (&) [46u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<40u>(clang::DiagnosticsEngine::Level, char const (&) [40u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<52u>(clang::DiagnosticsEngine::Level, char const (&) [52u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<51u>(clang::DiagnosticsEngine::Level, char const (&) [51u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<49u>(clang::DiagnosticsEngine::Level, char const (&) [49u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<42u>(clang::DiagnosticsEngine::Level, char const (&) [42u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<36u>(clang::DiagnosticsEngine::Level, char const (&) [36u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<44u>(clang::DiagnosticsEngine::Level, char const (&) [44u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<35u>(clang::DiagnosticsEngine::Level, char const (&) [35u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<66u>(clang::DiagnosticsEngine::Level, char const (&) [66u])
Unexecuted instantiation: unsigned int clang::DiagnosticsEngine::getCustomDiagID<43u>(clang::DiagnosticsEngine::Level, char const (&) [43u])
782
783
  /// Converts a diagnostic argument (as an intptr_t) into the string
784
  /// that represents it.
785
  void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
786
                          StringRef Modifier, StringRef Argument,
787
                          ArrayRef<ArgumentValue> PrevArgs,
788
                          SmallVectorImpl<char> &Output,
789
104k
                          ArrayRef<intptr_t> QualTypeVals) const {
790
104k
    ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
791
104k
                  ArgToStringCookie, QualTypeVals);
792
104k
  }
793
794
41.6k
  void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
795
41.6k
    ArgToStringFn = Fn;
796
41.6k
    ArgToStringCookie = Cookie;
797
41.6k
  }
798
799
  /// Note that the prior diagnostic was emitted by some other
800
  /// \c DiagnosticsEngine, and we may be attaching a note to that diagnostic.
801
136
  void notePriorDiagnosticFrom(const DiagnosticsEngine &Other) {
802
136
    LastDiagLevel = Other.LastDiagLevel;
803
136
  }
804
805
  /// Reset the state of the diagnostic object to its initial
806
  /// configuration.
807
  void Reset();
808
809
  //===--------------------------------------------------------------------===//
810
  // DiagnosticsEngine classification and reporting interfaces.
811
  //
812
813
  /// Determine whether the diagnostic is known to be ignored.
814
  ///
815
  /// This can be used to opportunistically avoid expensive checks when it's
816
  /// known for certain that the diagnostic has been suppressed at the
817
  /// specified location \p Loc.
818
  ///
819
  /// \param Loc The source location we are interested in finding out the
820
  /// diagnostic state. Can be null in order to query the latest state.
821
95.6M
  bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
822
95.6M
    return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
823
95.6M
           diag::Severity::Ignored;
824
95.6M
  }
825
826
  /// Based on the way the client configured the DiagnosticsEngine
827
  /// object, classify the specified diagnostic ID into a Level, consumable by
828
  /// the DiagnosticConsumer.
829
  ///
830
  /// To preserve invariant assumptions, this function should not be used to
831
  /// influence parse or semantic analysis actions. Instead consider using
832
  /// \c isIgnored().
833
  ///
834
  /// \param Loc The source location we are interested in finding out the
835
  /// diagnostic state. Can be null in order to query the latest state.
836
47.9k
  Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
837
47.9k
    return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
838
47.9k
  }
839
840
  /// Issue the message to the client.
841
  ///
842
  /// This actually returns an instance of DiagnosticBuilder which emits the
843
  /// diagnostics (through @c ProcessDiag) when it is destroyed.
844
  ///
845
  /// \param DiagID A member of the @c diag::kind enum.
846
  /// \param Loc Represents the source location associated with the diagnostic,
847
  /// which can be an invalid location if no position information is available.
848
  inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID);
849
  inline DiagnosticBuilder Report(unsigned DiagID);
850
851
  void Report(const StoredDiagnostic &storedDiag);
852
853
  /// Determine whethere there is already a diagnostic in flight.
854
27
  bool isDiagnosticInFlight() const {
855
27
    return CurDiagID != std::numeric_limits<unsigned>::max();
856
27
  }
857
858
  /// Set the "delayed" diagnostic that will be emitted once
859
  /// the current diagnostic completes.
860
  ///
861
  ///  If a diagnostic is already in-flight but the front end must
862
  ///  report a problem (e.g., with an inconsistent file system
863
  ///  state), this routine sets a "delayed" diagnostic that will be
864
  ///  emitted after the current diagnostic completes. This should
865
  ///  only be used for fatal errors detected at inconvenient
866
  ///  times. If emitting a delayed diagnostic causes a second delayed
867
  ///  diagnostic to be introduced, that second delayed diagnostic
868
  ///  will be ignored.
869
  ///
870
  /// \param DiagID The ID of the diagnostic being delayed.
871
  ///
872
  /// \param Arg1 A string argument that will be provided to the
873
  /// diagnostic. A copy of this string will be stored in the
874
  /// DiagnosticsEngine object itself.
875
  ///
876
  /// \param Arg2 A string argument that will be provided to the
877
  /// diagnostic. A copy of this string will be stored in the
878
  /// DiagnosticsEngine object itself.
879
  void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
880
                            StringRef Arg2 = "");
881
882
  /// Clear out the current diagnostic.
883
4.34M
  void Clear() { CurDiagID = std::numeric_limits<unsigned>::max(); }
884
885
  /// Return the value associated with this diagnostic flag.
886
5.50k
  StringRef getFlagValue() const { return FlagValue; }
887
888
private:
889
  // This is private state used by DiagnosticBuilder.  We put it here instead of
890
  // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
891
  // object.  This implementation choice means that we can only have one
892
  // diagnostic "in flight" at a time, but this seems to be a reasonable
893
  // tradeoff to keep these objects small.  Assertions verify that only one
894
  // diagnostic is in flight at a time.
895
  friend class Diagnostic;
896
  friend class DiagnosticBuilder;
897
  friend class DiagnosticErrorTrap;
898
  friend class DiagnosticIDs;
899
  friend class PartialDiagnostic;
900
901
  /// Report the delayed diagnostic.
902
  void ReportDelayed();
903
904
  /// The location of the current diagnostic that is in flight.
905
  SourceLocation CurDiagLoc;
906
907
  /// The ID of the current diagnostic that is in flight.
908
  ///
909
  /// This is set to std::numeric_limits<unsigned>::max() when there is no
910
  /// diagnostic in flight.
911
  unsigned CurDiagID;
912
913
  enum {
914
    /// The maximum number of arguments we can hold.
915
    ///
916
    /// We currently only support up to 10 arguments (%0-%9).  A single
917
    /// diagnostic with more than that almost certainly has to be simplified
918
    /// anyway.
919
    MaxArguments = 10,
920
  };
921
922
  /// The number of entries in Arguments.
923
  signed char NumDiagArgs;
924
925
  /// Specifies whether an argument is in DiagArgumentsStr or
926
  /// in DiagArguments.
927
  ///
928
  /// This is an array of ArgumentKind::ArgumentKind enum values, one for each
929
  /// argument.
930
  unsigned char DiagArgumentsKind[MaxArguments];
931
932
  /// Holds the values of each string argument for the current
933
  /// diagnostic.
934
  ///
935
  /// This is only used when the corresponding ArgumentKind is ak_std_string.
936
  std::string DiagArgumentsStr[MaxArguments];
937
938
  /// The values for the various substitution positions.
939
  ///
940
  /// This is used when the argument is not an std::string.  The specific
941
  /// value is mangled into an intptr_t and the interpretation depends on
942
  /// exactly what sort of argument kind it is.
943
  intptr_t DiagArgumentsVal[MaxArguments];
944
945
  /// The list of ranges added to this diagnostic.
946
  SmallVector<CharSourceRange, 8> DiagRanges;
947
948
  /// If valid, provides a hint with some code to insert, remove,
949
  /// or modify at a particular position.
950
  SmallVector<FixItHint, 8> DiagFixItHints;
951
952
2.16M
  DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
953
2.16M
    bool isPragma = L.isValid();
954
2.16M
    DiagnosticMapping Mapping =
955
2.16M
        DiagnosticMapping::Make(Map, /*IsUser=*/true, isPragma);
956
2.16M
957
2.16M
    // If this is a pragma mapping, then set the diagnostic mapping flags so
958
2.16M
    // that we override command line options.
959
2.16M
    if (isPragma) {
960
45.2k
      Mapping.setNoWarningAsError(true);
961
45.2k
      Mapping.setNoErrorAsFatal(true);
962
45.2k
    }
963
2.16M
964
2.16M
    return Mapping;
965
2.16M
  }
966
967
  /// Used to report a diagnostic that is finally fully formed.
968
  ///
969
  /// \returns true if the diagnostic was emitted, false if it was suppressed.
970
4.18M
  bool ProcessDiag() {
971
4.18M
    return Diags->ProcessDiag(*this);
972
4.18M
  }
973
974
  /// @name Diagnostic Emission
975
  /// @{
976
protected:
977
  friend class ASTReader;
978
  friend class ASTWriter;
979
980
  // Sema requires access to the following functions because the current design
981
  // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
982
  // access us directly to ensure we minimize the emitted code for the common
983
  // Sema::Diag() patterns.
984
  friend class Sema;
985
986
  /// Emit the current diagnostic and clear the diagnostic state.
987
  ///
988
  /// \param Force Emit the diagnostic regardless of suppression settings.
989
  bool EmitCurrentDiagnostic(bool Force = false);
990
991
164k
  unsigned getCurrentDiagID() const { return CurDiagID; }
992
993
29
  SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
994
995
  /// @}
996
};
997
998
/// RAII class that determines when any errors have occurred
999
/// between the time the instance was created and the time it was
1000
/// queried.
1001
class DiagnosticErrorTrap {
1002
  DiagnosticsEngine &Diag;
1003
  unsigned NumErrors;
1004
  unsigned NumUnrecoverableErrors;
1005
1006
public:
1007
  explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
1008
697k
      : Diag(Diag) { reset(); }
1009
1010
  /// Determine whether any errors have occurred since this
1011
  /// object instance was created.
1012
3.43k
  bool hasErrorOccurred() const {
1013
3.43k
    return Diag.TrapNumErrorsOccurred > NumErrors;
1014
3.43k
  }
1015
1016
  /// Determine whether any unrecoverable errors have occurred since this
1017
  /// object instance was created.
1018
27.9M
  bool hasUnrecoverableErrorOccurred() const {
1019
27.9M
    return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
1020
27.9M
  }
1021
1022
  /// Set to initial state of "no errors occurred".
1023
20.5M
  void reset() {
1024
20.5M
    NumErrors = Diag.TrapNumErrorsOccurred;
1025
20.5M
    NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
1026
20.5M
  }
1027
};
1028
1029
//===----------------------------------------------------------------------===//
1030
// DiagnosticBuilder
1031
//===----------------------------------------------------------------------===//
1032
1033
/// A little helper class used to produce diagnostics.
1034
///
1035
/// This is constructed by the DiagnosticsEngine::Report method, and
1036
/// allows insertion of extra information (arguments and source ranges) into
1037
/// the currently "in flight" diagnostic.  When the temporary for the builder
1038
/// is destroyed, the diagnostic is issued.
1039
///
1040
/// Note that many of these will be created as temporary objects (many call
1041
/// sites), so we want them to be small and we never want their address taken.
1042
/// This ensures that compilers with somewhat reasonable optimizers will promote
1043
/// the common fields to registers, eliminating increments of the NumArgs field,
1044
/// for example.
1045
class DiagnosticBuilder {
1046
  friend class DiagnosticsEngine;
1047
  friend class PartialDiagnostic;
1048
1049
  mutable DiagnosticsEngine *DiagObj = nullptr;
1050
  mutable unsigned NumArgs = 0;
1051
1052
  /// Status variable indicating if this diagnostic is still active.
1053
  ///
1054
  // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
1055
  // but LLVM is not currently smart enough to eliminate the null check that
1056
  // Emit() would end up with if we used that as our status variable.
1057
  mutable bool IsActive = false;
1058
1059
  /// Flag indicating that this diagnostic is being emitted via a
1060
  /// call to ForceEmit.
1061
  mutable bool IsForceEmit = false;
1062
1063
  DiagnosticBuilder() = default;
1064
1065
  explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
1066
4.34M
      : DiagObj(diagObj), IsActive(true) {
1067
4.34M
    assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
1068
4.34M
    diagObj->DiagRanges.clear();
1069
4.34M
    diagObj->DiagFixItHints.clear();
1070
4.34M
  }
1071
1072
protected:
1073
4.34M
  void FlushCounts() {
1074
4.34M
    DiagObj->NumDiagArgs = NumArgs;
1075
4.34M
  }
1076
1077
  /// Clear out the current diagnostic.
1078
6.75M
  void Clear() const {
1079
6.75M
    DiagObj = nullptr;
1080
6.75M
    IsActive = false;
1081
6.75M
    IsForceEmit = false;
1082
6.75M
  }
1083
1084
  /// Determine whether this diagnostic is still active.
1085
9.15M
  bool isActive() const { return IsActive; }
1086
1087
  /// Force the diagnostic builder to emit the diagnostic now.
1088
  ///
1089
  /// Once this function has been called, the DiagnosticBuilder object
1090
  /// should not be used again before it is destroyed.
1091
  ///
1092
  /// \returns true if a diagnostic was emitted, false if the
1093
  /// diagnostic was suppressed.
1094
6.75M
  bool Emit() {
1095
6.75M
    // If this diagnostic is inactive, then its soul was stolen by the copy ctor
1096
6.75M
    // (or by a subclass, as in SemaDiagnosticBuilder).
1097
6.75M
    if (!isActive()) 
return false4.80M
;
1098
1.94M
1099
1.94M
    // When emitting diagnostics, we set the final argument count into
1100
1.94M
    // the DiagnosticsEngine object.
1101
1.94M
    FlushCounts();
1102
1.94M
1103
1.94M
    // Process the diagnostic.
1104
1.94M
    bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
1105
1.94M
1106
1.94M
    // This diagnostic is dead.
1107
1.94M
    Clear();
1108
1.94M
1109
1.94M
    return Result;
1110
1.94M
  }
1111
1112
public:
1113
  /// Copy constructor.  When copied, this "takes" the diagnostic info from the
1114
  /// input and neuters it.
1115
2.40M
  DiagnosticBuilder(const DiagnosticBuilder &D) {
1116
2.40M
    DiagObj = D.DiagObj;
1117
2.40M
    IsActive = D.IsActive;
1118
2.40M
    IsForceEmit = D.IsForceEmit;
1119
2.40M
    D.Clear();
1120
2.40M
    NumArgs = D.NumArgs;
1121
2.40M
  }
1122
1123
  DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
1124
1125
  /// Emits the diagnostic.
1126
6.75M
  ~DiagnosticBuilder() {
1127
6.75M
    Emit();
1128
6.75M
  }
1129
1130
  /// Retrieve an empty diagnostic builder.
1131
0
  static DiagnosticBuilder getEmpty() {
1132
0
    return {};
1133
0
  }
1134
1135
  /// Forces the diagnostic to be emitted.
1136
192
  const DiagnosticBuilder &setForceEmit() const {
1137
192
    IsForceEmit = true;
1138
192
    return *this;
1139
192
  }
1140
1141
  /// Conversion of DiagnosticBuilder to bool always returns \c true.
1142
  ///
1143
  /// This allows is to be used in boolean error contexts (where \c true is
1144
  /// used to indicate that an error has occurred), like:
1145
  /// \code
1146
  /// return Diag(...);
1147
  /// \endcode
1148
3.93k
  operator bool() const { return true; }
1149
1150
229k
  void AddString(StringRef S) const {
1151
229k
    assert(isActive() && "Clients must not add to cleared diagnostic!");
1152
229k
    assert(NumArgs < DiagnosticsEngine::MaxArguments &&
1153
229k
           "Too many arguments to diagnostic!");
1154
229k
    DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
1155
229k
    DiagObj->DiagArgumentsStr[NumArgs++] = S;
1156
229k
  }
1157
1158
1.67M
  void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
1159
1.67M
    assert(isActive() && "Clients must not add to cleared diagnostic!");
1160
1.67M
    assert(NumArgs < DiagnosticsEngine::MaxArguments &&
1161
1.67M
           "Too many arguments to diagnostic!");
1162
1.67M
    DiagObj->DiagArgumentsKind[NumArgs] = Kind;
1163
1.67M
    DiagObj->DiagArgumentsVal[NumArgs++] = V;
1164
1.67M
  }
1165
1166
1.41M
  void AddSourceRange(const CharSourceRange &R) const {
1167
1.41M
    assert(isActive() && "Clients must not add to cleared diagnostic!");
1168
1.41M
    DiagObj->DiagRanges.push_back(R);
1169
1.41M
  }
1170
1171
256k
  void AddFixItHint(const FixItHint &Hint) const {
1172
256k
    assert(isActive() && "Clients must not add to cleared diagnostic!");
1173
256k
    if (!Hint.isNull())
1174
213k
      DiagObj->DiagFixItHints.push_back(Hint);
1175
256k
  }
1176
1177
55
  void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; }
1178
};
1179
1180
struct AddFlagValue {
1181
  StringRef Val;
1182
1183
55
  explicit AddFlagValue(StringRef V) : Val(V) {}
1184
};
1185
1186
/// Register a value for the flag in the current diagnostic. This
1187
/// value will be shown as the suffix "=value" after the flag name. It is
1188
/// useful in cases where the diagnostic flag accepts values (e.g.,
1189
/// -Rpass or -Wframe-larger-than).
1190
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1191
55
                                           const AddFlagValue V) {
1192
55
  DB.addFlagValue(V.Val);
1193
55
  return DB;
1194
55
}
1195
1196
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1197
207k
                                           StringRef S) {
1198
207k
  DB.AddString(S);
1199
207k
  return DB;
1200
207k
}
1201
1202
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1203
85.8k
                                           const char *Str) {
1204
85.8k
  DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
1205
85.8k
                  DiagnosticsEngine::ak_c_string);
1206
85.8k
  return DB;
1207
85.8k
}
1208
1209
250k
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
1210
250k
  DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1211
250k
  return DB;
1212
250k
}
1213
1214
// We use enable_if here to prevent that this overload is selected for
1215
// pointers or other arguments that are implicitly convertible to bool.
1216
template <typename T>
1217
inline
1218
typename std::enable_if<std::is_same<T, bool>::value,
1219
                        const DiagnosticBuilder &>::type
1220
85.6k
operator<<(const DiagnosticBuilder &DB, T I) {
1221
85.6k
  DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1222
85.6k
  return DB;
1223
85.6k
}
1224
1225
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1226
127k
                                           unsigned I) {
1227
127k
  DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
1228
127k
  return DB;
1229
127k
}
1230
1231
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1232
26.3k
                                           tok::TokenKind I) {
1233
26.3k
  DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
1234
26.3k
  return DB;
1235
26.3k
}
1236
1237
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1238
175k
                                           const IdentifierInfo *II) {
1239
175k
  DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
1240
175k
                  DiagnosticsEngine::ak_identifierinfo);
1241
175k
  return DB;
1242
175k
}
1243
1244
// Adds a DeclContext to the diagnostic. The enable_if template magic is here
1245
// so that we only match those arguments that are (statically) DeclContexts;
1246
// other arguments that derive from DeclContext (e.g., RecordDecls) will not
1247
// match.
1248
template <typename T>
1249
inline typename std::enable_if<
1250
    std::is_same<typename std::remove_const<T>::type, DeclContext>::value,
1251
    const DiagnosticBuilder &>::type
1252
32.2k
operator<<(const DiagnosticBuilder &DB, T *DC) {
1253
32.2k
  DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
1254
32.2k
                  DiagnosticsEngine::ak_declcontext);
1255
32.2k
  return DB;
1256
32.2k
}
std::__1::enable_if<std::is_same<std::__1::remove_const<clang::DeclContext>::type, clang::DeclContext>::value, clang::DiagnosticBuilder const&>::type clang::operator<<<clang::DeclContext>(clang::DiagnosticBuilder const&, clang::DeclContext*)
Line
Count
Source
1252
32.2k
operator<<(const DiagnosticBuilder &DB, T *DC) {
1253
32.2k
  DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
1254
32.2k
                  DiagnosticsEngine::ak_declcontext);
1255
32.2k
  return DB;
1256
32.2k
}
std::__1::enable_if<std::is_same<std::__1::remove_const<clang::DeclContext const>::type, clang::DeclContext>::value, clang::DiagnosticBuilder const&>::type clang::operator<<<clang::DeclContext const>(clang::DiagnosticBuilder const&, clang::DeclContext const*)
Line
Count
Source
1252
52
operator<<(const DiagnosticBuilder &DB, T *DC) {
1253
52
  DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
1254
52
                  DiagnosticsEngine::ak_declcontext);
1255
52
  return DB;
1256
52
}
1257
1258
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1259
1.27M
                                           SourceRange R) {
1260
1.27M
  DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1261
1.27M
  return DB;
1262
1.27M
}
1263
1264
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1265
14.1k
                                           ArrayRef<SourceRange> Ranges) {
1266
14.1k
  for (SourceRange R : Ranges)
1267
20.6k
    DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1268
14.1k
  return DB;
1269
14.1k
}
1270
1271
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1272
2.52k
                                           const CharSourceRange &R) {
1273
2.52k
  DB.AddSourceRange(R);
1274
2.52k
  return DB;
1275
2.52k
}
1276
1277
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1278
254k
                                           const FixItHint &Hint) {
1279
254k
  DB.AddFixItHint(Hint);
1280
254k
  return DB;
1281
254k
}
1282
1283
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1284
5.69k
                                           ArrayRef<FixItHint> Hints) {
1285
5.69k
  for (const FixItHint &Hint : Hints)
1286
1.32k
    DB.AddFixItHint(Hint);
1287
5.69k
  return DB;
1288
5.69k
}
1289
1290
/// A nullability kind paired with a bit indicating whether it used a
1291
/// context-sensitive keyword.
1292
using DiagNullabilityKind = std::pair<NullabilityKind, bool>;
1293
1294
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1295
                                    DiagNullabilityKind nullability);
1296
1297
inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
1298
4.34M
                                                   unsigned DiagID) {
1299
4.34M
  assert(CurDiagID == std::numeric_limits<unsigned>::max() &&
1300
4.34M
         "Multiple diagnostics in flight at once!");
1301
4.34M
  CurDiagLoc = Loc;
1302
4.34M
  CurDiagID = DiagID;
1303
4.34M
  FlagValue.clear();
1304
4.34M
  return DiagnosticBuilder(this);
1305
4.34M
}
1306
1307
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1308
6
                                           llvm::Error &&E) {
1309
6
  DB.AddString(toString(std::move(E)));
1310
6
  return DB;
1311
6
}
1312
1313
21.2k
inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
1314
21.2k
  return Report(SourceLocation(), DiagID);
1315
21.2k
}
1316
1317
//===----------------------------------------------------------------------===//
1318
// Diagnostic
1319
//===----------------------------------------------------------------------===//
1320
1321
/// A little helper class (which is basically a smart pointer that forwards
1322
/// info from DiagnosticsEngine) that allows clients to enquire about the
1323
/// currently in-flight diagnostic.
1324
class Diagnostic {
1325
  const DiagnosticsEngine *DiagObj;
1326
  StringRef StoredDiagMessage;
1327
1328
public:
1329
4.59M
  explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
1330
  Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
1331
150
      : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
1332
1333
391k
  const DiagnosticsEngine *getDiags() const { return DiagObj; }
1334
4.62M
  unsigned getID() const { return DiagObj->CurDiagID; }
1335
4.62M
  const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
1336
222k
  bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
1337
467k
  SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
1338
1339
540k
  unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
1340
1341
  /// Return the kind of the specified index.
1342
  ///
1343
  /// Based on the kind of argument, the accessors below can be used to get
1344
  /// the value.
1345
  ///
1346
  /// \pre Idx < getNumArgs()
1347
1.62M
  DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
1348
1.62M
    assert(Idx < getNumArgs() && "Argument index out of range!");
1349
1.62M
    return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
1350
1.62M
  }
1351
1352
  /// Return the provided argument string specified by \p Idx.
1353
  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_std_string
1354
198k
  const std::string &getArgStdStr(unsigned Idx) const {
1355
198k
    assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
1356
198k
           "invalid argument accessor!");
1357
198k
    return DiagObj->DiagArgumentsStr[Idx];
1358
198k
  }
1359
1360
  /// Return the specified C string argument.
1361
  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_c_string
1362
42.7k
  const char *getArgCStr(unsigned Idx) const {
1363
42.7k
    assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
1364
42.7k
           "invalid argument accessor!");
1365
42.7k
    return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
1366
42.7k
  }
1367
1368
  /// Return the specified signed integer argument.
1369
  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
1370
68.4k
  int getArgSInt(unsigned Idx) const {
1371
68.4k
    assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
1372
68.4k
           "invalid argument accessor!");
1373
68.4k
    return (int)DiagObj->DiagArgumentsVal[Idx];
1374
68.4k
  }
1375
1376
  /// Return the specified unsigned integer argument.
1377
  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
1378
60.3k
  unsigned getArgUInt(unsigned Idx) const {
1379
60.3k
    assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
1380
60.3k
           "invalid argument accessor!");
1381
60.3k
    return (unsigned)DiagObj->DiagArgumentsVal[Idx];
1382
60.3k
  }
1383
1384
  /// Return the specified IdentifierInfo argument.
1385
  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
1386
9.30k
  const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
1387
9.30k
    assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
1388
9.30k
           "invalid argument accessor!");
1389
9.30k
    return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
1390
9.30k
  }
1391
1392
  /// Return the specified non-string argument in an opaque form.
1393
  /// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
1394
676k
  intptr_t getRawArg(unsigned Idx) const {
1395
676k
    assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
1396
676k
           "invalid argument accessor!");
1397
676k
    return DiagObj->DiagArgumentsVal[Idx];
1398
676k
  }
1399
1400
  /// Return the number of source ranges associated with this diagnostic.
1401
159k
  unsigned getNumRanges() const {
1402
159k
    return DiagObj->DiagRanges.size();
1403
159k
  }
1404
1405
  /// \pre Idx < getNumRanges()
1406
152k
  const CharSourceRange &getRange(unsigned Idx) const {
1407
152k
    assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
1408
152k
    return DiagObj->DiagRanges[Idx];
1409
152k
  }
1410
1411
  /// Return an array reference for this diagnostic's ranges.
1412
41.7k
  ArrayRef<CharSourceRange> getRanges() const {
1413
41.7k
    return DiagObj->DiagRanges;
1414
41.7k
  }
1415
1416
160k
  unsigned getNumFixItHints() const {
1417
160k
    return DiagObj->DiagFixItHints.size();
1418
160k
  }
1419
1420
965
  const FixItHint &getFixItHint(unsigned Idx) const {
1421
965
    assert(Idx < getNumFixItHints() && "Invalid index!");
1422
965
    return DiagObj->DiagFixItHints[Idx];
1423
965
  }
1424
1425
41.7k
  ArrayRef<FixItHint> getFixItHints() const {
1426
41.7k
    return DiagObj->DiagFixItHints;
1427
41.7k
  }
1428
1429
  /// Format this diagnostic into a string, substituting the
1430
  /// formal arguments into the %0 slots.
1431
  ///
1432
  /// The result is appended onto the \p OutStr array.
1433
  void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
1434
1435
  /// Format the given format-string into the output buffer using the
1436
  /// arguments stored in this diagnostic.
1437
  void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
1438
                        SmallVectorImpl<char> &OutStr) const;
1439
};
1440
1441
/**
1442
 * Represents a diagnostic in a form that can be retained until its
1443
 * corresponding source manager is destroyed.
1444
 */
1445
class StoredDiagnostic {
1446
  unsigned ID;
1447
  DiagnosticsEngine::Level Level;
1448
  FullSourceLoc Loc;
1449
  std::string Message;
1450
  std::vector<CharSourceRange> Ranges;
1451
  std::vector<FixItHint> FixIts;
1452
1453
public:
1454
  StoredDiagnostic() = default;
1455
  StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
1456
  StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1457
                   StringRef Message);
1458
  StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1459
                   StringRef Message, FullSourceLoc Loc,
1460
                   ArrayRef<CharSourceRange> Ranges,
1461
                   ArrayRef<FixItHint> Fixits);
1462
1463
  /// Evaluates true when this object stores a diagnostic.
1464
0
  explicit operator bool() const { return !Message.empty(); }
1465
1466
22.5k
  unsigned getID() const { return ID; }
1467
9.06k
  DiagnosticsEngine::Level getLevel() const { return Level; }
1468
26.5k
  const FullSourceLoc &getLocation() const { return Loc; }
1469
1.93k
  StringRef getMessage() const { return Message; }
1470
1471
79
  void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
1472
1473
  using range_iterator = std::vector<CharSourceRange>::const_iterator;
1474
1475
225
  range_iterator range_begin() const { return Ranges.begin(); }
1476
151
  range_iterator range_end() const { return Ranges.end(); }
1477
  unsigned range_size() const { return Ranges.size(); }
1478
1479
616
  ArrayRef<CharSourceRange> getRanges() const {
1480
616
    return llvm::makeArrayRef(Ranges);
1481
616
  }
1482
1483
  using fixit_iterator = std::vector<FixItHint>::const_iterator;
1484
1485
187
  fixit_iterator fixit_begin() const { return FixIts.begin(); }
1486
150
  fixit_iterator fixit_end() const { return FixIts.end(); }
1487
  unsigned fixit_size() const { return FixIts.size(); }
1488
1489
614
  ArrayRef<FixItHint> getFixIts() const {
1490
614
    return llvm::makeArrayRef(FixIts);
1491
614
  }
1492
};
1493
1494
/// Abstract interface, implemented by clients of the front-end, which
1495
/// formats and prints fully processed diagnostics.
1496
class DiagnosticConsumer {
1497
protected:
1498
  unsigned NumWarnings = 0;       ///< Number of warnings reported
1499
  unsigned NumErrors = 0;         ///< Number of errors reported
1500
1501
public:
1502
166k
  DiagnosticConsumer() = default;
1503
  virtual ~DiagnosticConsumer();
1504
1505
85.8k
  unsigned getNumErrors() const { return NumErrors; }
1506
41.8k
  unsigned getNumWarnings() const { return NumWarnings; }
1507
2
  virtual void clear() { NumWarnings = NumErrors = 0; }
1508
1509
  /// Callback to inform the diagnostic client that processing
1510
  /// of a source file is beginning.
1511
  ///
1512
  /// Note that diagnostics may be emitted outside the processing of a source
1513
  /// file, for example during the parsing of command line options. However,
1514
  /// diagnostics with source range information are required to only be emitted
1515
  /// in between BeginSourceFile() and EndSourceFile().
1516
  ///
1517
  /// \param LangOpts The language options for the source file being processed.
1518
  /// \param PP The preprocessor object being used for the source; this is
1519
  /// optional, e.g., it may not be present when processing AST source files.
1520
  virtual void BeginSourceFile(const LangOptions &LangOpts,
1521
1.50k
                               const Preprocessor *PP = nullptr) {}
1522
1523
  /// Callback to inform the diagnostic client that processing
1524
  /// of a source file has ended.
1525
  ///
1526
  /// The diagnostic client should assume that any objects made available via
1527
  /// BeginSourceFile() are inaccessible.
1528
4.35k
  virtual void EndSourceFile() {}
1529
1530
  /// Callback to inform the diagnostic client that processing of all
1531
  /// source files has ended.
1532
64.0k
  virtual void finish() {}
1533
1534
  /// Indicates whether the diagnostics handled by this
1535
  /// DiagnosticConsumer should be included in the number of diagnostics
1536
  /// reported by DiagnosticsEngine.
1537
  ///
1538
  /// The default implementation returns true.
1539
  virtual bool IncludeInDiagnosticCounts() const;
1540
1541
  /// Handle this diagnostic, reporting it to the user or
1542
  /// capturing it to a log as needed.
1543
  ///
1544
  /// The default implementation just keeps track of the total number of
1545
  /// warnings and errors.
1546
  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1547
                                const Diagnostic &Info);
1548
};
1549
1550
/// A diagnostic client that ignores all diagnostics.
1551
class IgnoringDiagConsumer : public DiagnosticConsumer {
1552
  virtual void anchor();
1553
1554
  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1555
38
                        const Diagnostic &Info) override {
1556
38
    // Just ignore it.
1557
38
  }
1558
};
1559
1560
/// Diagnostic consumer that forwards diagnostics along to an
1561
/// existing, already-initialized diagnostic consumer.
1562
///
1563
class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
1564
  DiagnosticConsumer &Target;
1565
1566
public:
1567
1.33k
  ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {}
1568
  ~ForwardingDiagnosticConsumer() override;
1569
1570
  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1571
                        const Diagnostic &Info) override;
1572
  void clear() override;
1573
1574
  bool IncludeInDiagnosticCounts() const override;
1575
};
1576
1577
// Struct used for sending info about how a type should be printed.
1578
struct TemplateDiffTypes {
1579
  intptr_t FromType;
1580
  intptr_t ToType;
1581
  unsigned PrintTree : 1;
1582
  unsigned PrintFromType : 1;
1583
  unsigned ElideType : 1;
1584
  unsigned ShowColors : 1;
1585
1586
  // The printer sets this variable to true if the template diff was used.
1587
  unsigned TemplateDiffUsed : 1;
1588
};
1589
1590
/// Special character that the diagnostic printer will use to toggle the bold
1591
/// attribute.  The character itself will be not be printed.
1592
const char ToggleHighlight = 127;
1593
1594
/// ProcessWarningOptions - Initialize the diagnostic client and process the
1595
/// warning options specified on the command line.
1596
void ProcessWarningOptions(DiagnosticsEngine &Diags,
1597
                           const DiagnosticOptions &Opts,
1598
                           bool ReportDiags = true);
1599
1600
} // namespace clang
1601
1602
#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H