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 #include "llvm/ADT/ArrayRef.h" 11 #include "llvm/ADT/StringRef.h" 12 #include "llvm/Support/DataTypes.h" 13 14 namespace diagtool { 15 16 struct DiagnosticRecord { 17 const char *NameStr; 18 short DiagID; 19 uint8_t NameLen; 20 21 llvm::StringRef getName() const { 22 return llvm::StringRef(NameStr, NameLen); 23 } 24 25 bool operator<(const DiagnosticRecord &Other) const { 26 return getName() < Other.getName(); 27 } 28 }; 29 30 /// \brief Get every diagnostic in the system, sorted by name. 31 llvm::ArrayRef<DiagnosticRecord> getBuiltinDiagnosticsByName(); 32 33 /// \brief Get a diagnostic by its ID. 34 const DiagnosticRecord &getDiagnosticForID(short DiagID); 35 36 37 struct GroupRecord { 38 // Be safe with the size of 'NameLen' because we don't statically check if 39 // the size will fit in the field; the struct size won't decrease with a 40 // shorter type anyway. 41 size_t NameLen; 42 const char *NameStr; 43 const short *Members; 44 const short *SubGroups; 45 46 llvm::StringRef getName() const { 47 return llvm::StringRef(NameStr, NameLen); 48 } 49 50 template<typename RecordType> 51 class group_iterator { 52 const short *CurrentID; 53 54 friend struct GroupRecord; 55 group_iterator(const short *Start) : CurrentID(Start) { 56 if (CurrentID && *CurrentID == -1) 57 CurrentID = 0; 58 } 59 60 public: 61 typedef RecordType value_type; 62 typedef const value_type & reference; 63 typedef const value_type * pointer; 64 typedef std::forward_iterator_tag iterator_category; 65 typedef std::ptrdiff_t difference_type; 66 67 inline reference operator*() const; 68 inline pointer operator->() const { 69 return &operator*(); 70 } 71 72 inline short getID() const { 73 return *CurrentID; 74 } 75 76 group_iterator &operator++() { 77 ++CurrentID; 78 if (*CurrentID == -1) 79 CurrentID = 0; 80 return *this; 81 } 82 83 bool operator==(group_iterator &Other) const { 84 return CurrentID == Other.CurrentID; 85 } 86 87 bool operator!=(group_iterator &Other) const { 88 return CurrentID != Other.CurrentID; 89 } 90 }; 91 92 typedef group_iterator<GroupRecord> subgroup_iterator; 93 subgroup_iterator subgroup_begin() const { 94 return SubGroups; 95 } 96 subgroup_iterator subgroup_end() const { 97 return 0; 98 } 99 100 typedef group_iterator<DiagnosticRecord> diagnostics_iterator; 101 diagnostics_iterator diagnostics_begin() const { 102 return Members; 103 } 104 diagnostics_iterator diagnostics_end() const { 105 return 0; 106 } 107 108 bool operator<(const GroupRecord &Other) const { 109 return getName() < Other.getName(); 110 } 111 }; 112 113 /// \brief Get every diagnostic group in the system, sorted by name. 114 llvm::ArrayRef<GroupRecord> getDiagnosticGroups(); 115 116 template<> 117 inline GroupRecord::subgroup_iterator::reference 118 GroupRecord::subgroup_iterator::operator*() const { 119 return getDiagnosticGroups()[*CurrentID]; 120 } 121 122 template<> 123 inline GroupRecord::diagnostics_iterator::reference 124 GroupRecord::diagnostics_iterator::operator*() const { 125 return getDiagnosticForID(*CurrentID); 126 } 127 } // end namespace diagtool 128 129