Coverage Report

Created: 2020-02-25 14:32

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