1 //===- DiagnosticNames.h - Defines a table of all builtin diagnostics ------==//
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 #ifndef LLVM_CLANG_TOOLS_DIAGTOOL_DIAGNOSTICNAMES_H
10 #define LLVM_CLANG_TOOLS_DIAGTOOL_DIAGNOSTICNAMES_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Support/DataTypes.h"
15 
16 namespace diagtool {
17 
18   struct DiagnosticRecord {
19     const char *NameStr;
20     short DiagID;
21     uint8_t NameLen;
22 
getNameDiagnosticRecord23     llvm::StringRef getName() const {
24       return llvm::StringRef(NameStr, NameLen);
25     }
26 
27     bool operator<(const DiagnosticRecord &Other) const {
28       return getName() < Other.getName();
29     }
30   };
31 
32   /// Get every diagnostic in the system, sorted by name.
33   llvm::ArrayRef<DiagnosticRecord> getBuiltinDiagnosticsByName();
34 
35   /// Get a diagnostic by its ID.
36   const DiagnosticRecord &getDiagnosticForID(short DiagID);
37 
38 
39   struct GroupRecord {
40     uint16_t NameOffset;
41     uint16_t Members;
42     uint16_t SubGroups;
43 
44     llvm::StringRef getName() const;
45 
46     template<typename RecordType>
47     class group_iterator {
48       const short *CurrentID;
49 
50       friend struct GroupRecord;
group_iteratorGroupRecord51       group_iterator(const short *Start) : CurrentID(Start) {
52         if (CurrentID && *CurrentID == -1)
53           CurrentID = nullptr;
54       }
55 
56     public:
57       typedef RecordType                 value_type;
58       typedef const value_type &         reference;
59       typedef const value_type *         pointer;
60       typedef std::forward_iterator_tag  iterator_category;
61       typedef std::ptrdiff_t             difference_type;
62 
63       inline reference operator*() const;
64       inline pointer operator->() const {
65         return &operator*();
66       }
67 
getIDGroupRecord68       inline short getID() const {
69         return *CurrentID;
70       }
71 
72       group_iterator &operator++() {
73         ++CurrentID;
74         if (*CurrentID == -1)
75           CurrentID = nullptr;
76         return *this;
77       }
78 
79       bool operator==(const group_iterator &Other) const {
80         return CurrentID == Other.CurrentID;
81       }
82 
83       bool operator!=(const group_iterator &Other) const {
84         return CurrentID != Other.CurrentID;
85       }
86     };
87 
88     typedef group_iterator<GroupRecord> subgroup_iterator;
89     subgroup_iterator subgroup_begin() const;
90     subgroup_iterator subgroup_end() const;
91     llvm::iterator_range<subgroup_iterator> subgroups() const;
92 
93     typedef group_iterator<DiagnosticRecord> diagnostics_iterator;
94     diagnostics_iterator diagnostics_begin() const;
95     diagnostics_iterator diagnostics_end() const;
96     llvm::iterator_range<diagnostics_iterator> diagnostics() const;
97 
98     bool operator<(llvm::StringRef Other) const {
99       return getName() < Other;
100     }
101   };
102 
103   /// Get every diagnostic group in the system, sorted by name.
104   llvm::ArrayRef<GroupRecord> getDiagnosticGroups();
105 
106   template<>
107   inline GroupRecord::subgroup_iterator::reference
108   GroupRecord::subgroup_iterator::operator*() const {
109     return getDiagnosticGroups()[*CurrentID];
110   }
111 
112   template<>
113   inline GroupRecord::diagnostics_iterator::reference
114   GroupRecord::diagnostics_iterator::operator*() const {
115     return getDiagnosticForID(*CurrentID);
116   }
117 } // end namespace diagtool
118 
119 #endif
120