1 //===- DiagnosticNames.cpp - 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 #include "DiagnosticNames.h" 10 #include "clang/Basic/AllDiagnostics.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/StringTable.h" 13 14 using namespace clang; 15 using namespace diagtool; 16 17 static const DiagnosticRecord BuiltinDiagnosticsByName[] = { 18 #define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) }, 19 #include "clang/Basic/DiagnosticIndexName.inc" 20 #undef DIAG_NAME_INDEX 21 }; 22 23 llvm::ArrayRef<DiagnosticRecord> diagtool::getBuiltinDiagnosticsByName() { 24 return llvm::ArrayRef(BuiltinDiagnosticsByName); 25 } 26 27 // FIXME: Is it worth having two tables, especially when this one can get 28 // out of sync easily? 29 static const DiagnosticRecord BuiltinDiagnosticsByID[] = { 30 #define DIAG(ENUM, CLASS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ 31 SHOWINSYSHEADER, SHOWINSYSMACRO, DEFER, CATEGORY) \ 32 {#ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t)}, 33 #include "clang/Basic/AllDiagnosticKinds.inc" 34 #undef DIAG 35 }; 36 37 static bool orderByID(const DiagnosticRecord &Left, 38 const DiagnosticRecord &Right) { 39 return Left.DiagID < Right.DiagID; 40 } 41 42 const DiagnosticRecord &diagtool::getDiagnosticForID(short DiagID) { 43 DiagnosticRecord Key = {nullptr, DiagID, 0}; 44 45 // The requirement for lower_bound to produce a valid result it is 46 // enough if the BuiltinDiagnosticsByID is partitioned (by DiagID), 47 // but as we want this function to work for all possible values of 48 // DiagID sent in as argument it is better to right away check if 49 // BuiltinDiagnosticsByID is sorted. 50 assert(llvm::is_sorted(BuiltinDiagnosticsByID, orderByID) && 51 "IDs in BuiltinDiagnosticsByID must be sorted."); 52 const DiagnosticRecord *Result = 53 llvm::lower_bound(BuiltinDiagnosticsByID, Key, orderByID); 54 assert(Result && "diagnostic not found; table may be out of date"); 55 return *Result; 56 } 57 58 59 #define GET_DIAG_ARRAYS 60 #include "clang/Basic/DiagnosticGroups.inc" 61 #undef GET_DIAG_ARRAYS 62 63 // Second the table of options, sorted by name for fast binary lookup. 64 static const GroupRecord OptionTable[] = { 65 #define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \ 66 {FlagNameOffset, Members, SubGroups}, 67 #include "clang/Basic/DiagnosticGroups.inc" 68 #undef DIAG_ENTRY 69 }; 70 71 llvm::StringRef GroupRecord::getName() const { 72 return DiagGroupNames[NameOffset]; 73 } 74 75 GroupRecord::subgroup_iterator GroupRecord::subgroup_begin() const { 76 return DiagSubGroups + SubGroups; 77 } 78 79 GroupRecord::subgroup_iterator GroupRecord::subgroup_end() const { 80 return nullptr; 81 } 82 83 llvm::iterator_range<diagtool::GroupRecord::subgroup_iterator> 84 GroupRecord::subgroups() const { 85 return llvm::make_range(subgroup_begin(), subgroup_end()); 86 } 87 88 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_begin() const { 89 return DiagArrays + Members; 90 } 91 92 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_end() const { 93 return nullptr; 94 } 95 96 llvm::iterator_range<diagtool::GroupRecord::diagnostics_iterator> 97 GroupRecord::diagnostics() const { 98 return llvm::make_range(diagnostics_begin(), diagnostics_end()); 99 } 100 101 llvm::ArrayRef<GroupRecord> diagtool::getDiagnosticGroups() { 102 return llvm::ArrayRef(OptionTable); 103 } 104