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