Home | History | Annotate | Download | only in diagtool
      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