https://github.com/dzbarsky updated https://github.com/llvm/llvm-project/pull/202624
>From b87204ec87b6a5e090018a8508c0cd7d82f9cd45 Mon Sep 17 00:00:00 2001 From: David Zbarsky <[email protected]> Date: Thu, 11 Jun 2026 15:29:04 -0400 Subject: [PATCH 1/3] [clang] Deduplicate builtin diagnostic descriptions Clang currently emits one character array per builtin diagnostic description and a separate 32-bit offset for every diagnostic. Exact duplicate descriptions are therefore stored repeatedly, and the offset table alone costs about 29 KiB. Add each distinct description to the existing DiagnosticStableIDs.inc output. Emit pointer-free character storage and reference each generated offset as DIAG_DESC_OFFSET_<diagnostic>. Store the 20-bit offset and 12-bit length inside the existing 10-byte StaticDiagInfoRec by reducing the diagnostic group index from 15 to 14 bits and repacking its two flags. TableGen and compile-time checks enforce all three field limits. On arm64 macOS Release builds from the same revision, fully stripped standalone clang decreases from 94,570,224 to 94,520,688 bytes, saving 49,536 bytes (0.052380%). DiagnosticIDs.cpp.o decreases from 1,081,768 to 1,029,272 bytes, saving 52,496 bytes (4.852797%), and libclangBasic.a decreases from 6,775,200 to 6,722,704 bytes, saving 52,496 bytes (0.774826%). At this point in the downstream LLVM 22 patch stack, the stripped all-tools multicall binary decreases from 143,039,208 to 142,989,664 bytes, saving 49,544 bytes (0.0346%). An out-of-tree benchmark performing 36.495 million getDescription() lookups measured average user CPU time decreasing from 270.196 ms to 261.598 ms (3.181953%). Wall time was noisy under concurrent builds, so this is treated as evidence of no lookup regression rather than a claimed speedup. Validation: - Built standalone clang and BasicTests in Release mode. - BasicTests passed 101 tests; 3 Release-only death tests were skipped. - Compared all 7,299 generated descriptions with getDescription() exactly. - Compared representative baseline and candidate diagnostic output byte-for-byte: 806 bytes over 13 lines with identical exit status. --- clang/lib/Basic/DiagnosticIDs.cpp | 58 +++++-------------- .../TableGen/ClangDiagnosticsEmitter.cpp | 27 ++++++++- .../llvm/TableGen/StringToOffsetTable.h | 6 ++ llvm/lib/TableGen/StringToOffsetTable.cpp | 15 +++-- 4 files changed, 57 insertions(+), 49 deletions(-) diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index 4172ef1f66da8c..4485e6120a654c 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -36,40 +36,8 @@ struct StaticDiagInfoRec; #include "clang/Basic/DiagnosticStableIDs.inc" #undef GET_DIAG_STABLE_ID_ARRAYS -// Store the descriptions in a separate table to avoid pointers that need to -// be relocated, and also decrease the amount of data needed on 64-bit -// platforms. See "How To Write Shared Libraries" by Ulrich Drepper. -struct StaticDiagInfoDescriptionStringTable { -#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY, STABLE_ID, \ - LEGACY_STABLE_IDS) \ - char ENUM##_desc[sizeof(DESC)]; -#include "clang/Basic/AllDiagnosticKinds.inc" -#undef DIAG -}; - -const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = { -#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY, STABLE_ID, \ - LEGACY_STABLE_IDS) \ - DESC, -#include "clang/Basic/AllDiagnosticKinds.inc" -#undef DIAG -}; - extern const StaticDiagInfoRec StaticDiagInfo[]; -// Stored separately from StaticDiagInfoRec to pack better. Otherwise, -// StaticDiagInfoRec would have extra padding on 64-bit platforms. -const uint32_t StaticDiagInfoDescriptionOffsets[] = { -#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY, STABLE_ID, \ - LEGACY_STABLE_IDS) \ - offsetof(StaticDiagInfoDescriptionStringTable, ENUM##_desc), -#include "clang/Basic/AllDiagnosticKinds.inc" -#undef DIAG -}; - const uint32_t StaticDiagInfoStableIDOffsets[] = { #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY, STABLE_ID, \ @@ -111,25 +79,26 @@ struct StaticDiagInfoRec { uint16_t WarnNoWerror : 1; LLVM_PREFERRED_TYPE(bool) uint16_t WarnShowInSystemHeader : 1; + LLVM_PREFERRED_TYPE(diag::Group) + uint16_t OptionGroupIndex : 14; LLVM_PREFERRED_TYPE(bool) uint16_t WarnShowInSystemMacro : 1; - - LLVM_PREFERRED_TYPE(diag::Group) - uint16_t OptionGroupIndex : 15; LLVM_PREFERRED_TYPE(bool) uint16_t Deferrable : 1; - uint16_t DescriptionLen; + uint16_t DescriptionOffsetLow; + uint16_t DescriptionOffsetHigh : 4; + uint16_t DescriptionLen : 12; unsigned getOptionGroupIndex() const { return OptionGroupIndex; } StringRef getDescription() const { - size_t MyIndex = this - &StaticDiagInfo[0]; - uint32_t StringOffset = StaticDiagInfoDescriptionOffsets[MyIndex]; - const char* Table = reinterpret_cast<const char*>(&StaticDiagInfoDescriptions); - return StringRef(&Table[StringOffset], DescriptionLen); + uint32_t Offset = + DescriptionOffsetLow | (uint32_t(DescriptionOffsetHigh) << 16); + return StringRef(StaticDiagInfoDescriptionsStorage + Offset, + DescriptionLen); } StringRef getStableID() const { @@ -159,6 +128,9 @@ struct StaticDiagInfoRec { return DiagID < RHS.DiagID; } }; +static_assert(sizeof(StaticDiagInfoRec) == 10); +static_assert(static_cast<unsigned>(diag::Group::NUM_GROUPS) < (1U << 14), + "too many diagnostic groups for StaticDiagInfoRec"); #define STRINGIFY_NAME(NAME) #NAME #define VALIDATE_DIAG_SIZE(NAME) \ @@ -201,9 +173,11 @@ const StaticDiagInfoRec StaticDiagInfo[] = { CATEGORY, \ NOWERROR, \ SHOWINSYSHEADER, \ - SHOWINSYSMACRO, \ GROUP, \ - DEFERRABLE, \ + SHOWINSYSMACRO, \ + DEFERRABLE, \ + uint16_t(DIAG_DESC_OFFSET_##ENUM), \ + uint16_t(DIAG_DESC_OFFSET_##ENUM >> 16), \ STR_SIZE(DESC, uint16_t)}, #include "clang/Basic/DiagnosticCommonKinds.inc" #include "clang/Basic/DiagnosticDriverKinds.inc" diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index 57909baf9d2f55..2fe7dc64fbdc6d 100644 --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -1801,10 +1801,11 @@ class DiagStableIDsMap { /// static constexpr llvm::StringTable DiagStableIds; /// #endif /// \endcode - void emit(raw_ostream &OS) const { + void emit(raw_ostream &OS, const RecordKeeper &Records) const { OS << "\n#ifdef GET_DIAG_STABLE_ID_ARRAYS\n"; emitStableIDs(OS); emitLegacyStableIDs(OS); + emitDescriptions(OS, Records); OS << "#endif // GET_DIAG_STABLE_ID_ARRAYS\n\n"; } @@ -1860,6 +1861,28 @@ class DiagStableIDsMap { } OS << "};\n\n"; } + + static void emitDescriptions(raw_ostream &OS, const RecordKeeper &Records) { + DiagnosticTextBuilder DiagTextBuilder(Records); + StringToOffsetTable Descriptions; + + OS << "enum {\n"; + for (const Record &R : + make_pointee_range(Records.getAllDerivedDefinitions("Diagnostic"))) { + std::string Description = DiagTextBuilder.buildForDefinition(&R); + if (Description.size() >= (1U << 12)) + PrintFatalError(R.getLoc(), + "diagnostic description exceeds 12-bit length limit"); + + unsigned Offset = Descriptions.GetOrAddStringOffset(Description); + OS << " DIAG_DESC_OFFSET_" << R.getName() << " = " << Offset << ",\n"; + } + OS << "};\n\n"; + + if (Descriptions.size() >= (1U << 20)) + PrintFatalError("diagnostic descriptions exceed 20-bit offset limit"); + Descriptions.EmitStringTableStorageDef(OS, "StaticDiagInfoDescriptions"); + } }; } // namespace @@ -1867,7 +1890,7 @@ class DiagStableIDsMap { void clang::EmitClangDiagsStableIDs(const RecordKeeper &Records, raw_ostream &OS) { DiagStableIDsMap StableIDs(Records); - StableIDs.emit(OS); + StableIDs.emit(OS, Records); } /// ClangDiagsDefsEmitter - The top-level class emits .def files containing diff --git a/llvm/include/llvm/TableGen/StringToOffsetTable.h b/llvm/include/llvm/TableGen/StringToOffsetTable.h index 075e16bdace4df..159ef3639ea391 100644 --- a/llvm/include/llvm/TableGen/StringToOffsetTable.h +++ b/llvm/include/llvm/TableGen/StringToOffsetTable.h @@ -67,6 +67,12 @@ class StringToOffsetTable { // valid identifiers to declare. LLVM_ABI void EmitStringTableDef(raw_ostream &OS, const Twine &Name) const; + // Emit only the character storage used by a string table definition. + // + // This preserves the large-string handling of EmitStringTableDef without + // emitting an llvm::StringTable object. + void EmitStringTableStorageDef(raw_ostream &OS, const Twine &Name) const; + // Emit the string as one single string. LLVM_ABI void EmitString(raw_ostream &O) const; }; diff --git a/llvm/lib/TableGen/StringToOffsetTable.cpp b/llvm/lib/TableGen/StringToOffsetTable.cpp index 0be309e622f128..e01da8befbede5 100644 --- a/llvm/lib/TableGen/StringToOffsetTable.cpp +++ b/llvm/lib/TableGen/StringToOffsetTable.cpp @@ -26,10 +26,9 @@ unsigned StringToOffsetTable::GetOrAddStringOffset(StringRef Str) { return II->second; } -void StringToOffsetTable::EmitStringTableDef(raw_ostream &OS, - const Twine &Name) const { - // This generates a `llvm::StringTable` which expects that entries are null - // terminated. So fail with an error if `AppendZero` is false. +void StringToOffsetTable::EmitStringTableStorageDef(raw_ostream &OS, + const Twine &Name) const { + // String table entries must be null terminated. if (!AppendZero) PrintFatalError("llvm::StringTable requires null terminated strings"); @@ -82,11 +81,17 @@ void StringToOffsetTable::EmitStringTableDef(raw_ostream &OS, } OS << LineSep << (UseChars ? "};" : " ;"); - OS << formatv(R"( + OS << R"( #ifdef __GNUC__ #pragma GCC diagnostic pop #endif +)"; +} +void StringToOffsetTable::EmitStringTableDef(raw_ostream &OS, + const Twine &Name) const { + EmitStringTableStorageDef(OS, Name); + OS << formatv(R"( {1} llvm::StringTable {2}{0} = {0}Storage; )", >From 1c247e20279d2e70c5c9f5f610551f660d94e399 Mon Sep 17 00:00:00 2001 From: David Zbarsky <[email protected]> Date: Thu, 11 Jun 2026 15:29:05 -0400 Subject: [PATCH 2/3] [clang][diagtool] Store compact diagnostic name offsets Store each builtin diagnostic name once in BuiltinDiagnosticNameStorage and replace DiagnosticRecord::NameStr with a naturally aligned 24-bit offset, reducing DiagnosticRecord from 16 to 6 bytes. Replace the duplicate ID-sorted DiagnosticRecord table with a direct uint16_t index from diagnostic ID to the canonical name-sorted table. In an arm64 Release build, DiagnosticNames.cpp.o decreases from 839,232 to 349,576 bytes (-489,656). __DATA,__const decreases by 233,600 bytes and __TEXT,__cstring decreases by 240,663 bytes while __TEXT,__const increases by 304,704 bytes; object relocations fall from 14,628 to 33. A linked lookup executable exercising both lookup orders decreases from 496,152 to 331,160 bytes (-164,992), its stripped form decreases from 495,968 to 330,864 bytes (-165,104), and its fixups fall from 14,604 to 4. Validation: - Compiled the compact DiagnosticNames.cpp object. - Exhaustively compared name-ordered and ID-ordered lookup results for all 7,300 diagnostics. - Linked and ran identical baseline and compact lookup executables; both produced the same aggregate output hash. --- clang/tools/diagtool/DiagnosticNames.cpp | 74 +++++++----- clang/tools/diagtool/DiagnosticNames.h | 147 +++++++++++------------ 2 files changed, 114 insertions(+), 107 deletions(-) diff --git a/clang/tools/diagtool/DiagnosticNames.cpp b/clang/tools/diagtool/DiagnosticNames.cpp index 1538167022aca5..0c5f6bc771cff4 100644 --- a/clang/tools/diagtool/DiagnosticNames.cpp +++ b/clang/tools/diagtool/DiagnosticNames.cpp @@ -10,53 +10,67 @@ #include "clang/Basic/AllDiagnostics.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringTable.h" +#include <array> +#include <cstddef> +#include <cstdint> using namespace clang; using namespace diagtool; -static const DiagnosticRecord BuiltinDiagnosticsByName[] = { -#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) }, +struct BuiltinDiagnosticNameStorage { +#define DIAG_NAME_INDEX(ENUM) char ENUM[sizeof(#ENUM)]; #include "clang/Basic/DiagnosticIndexName.inc" #undef DIAG_NAME_INDEX }; +static_assert(sizeof(BuiltinDiagnosticNameStorage) <= uint64_t(1) << 24); + +static constexpr BuiltinDiagnosticNameStorage BuiltinDiagnosticNames = { +#define DIAG_NAME_INDEX(ENUM) #ENUM, +#include "clang/Basic/DiagnosticIndexName.inc" +#undef DIAG_NAME_INDEX +}; + +#define DIAGNOSTIC_RECORD(ENUM) \ + {diag::ENUM, uint16_t(offsetof(BuiltinDiagnosticNameStorage, ENUM)), \ + uint8_t(offsetof(BuiltinDiagnosticNameStorage, ENUM) >> 16), \ + STR_SIZE(#ENUM, uint8_t)} + +static constexpr DiagnosticRecord BuiltinDiagnosticsByName[] = { +#define DIAG_NAME_INDEX(ENUM) DIAGNOSTIC_RECORD(ENUM), +#include "clang/Basic/DiagnosticIndexName.inc" +#undef DIAG_NAME_INDEX +}; +static_assert(std::size(BuiltinDiagnosticsByName) < (1U << 16)); +#undef DIAGNOSTIC_RECORD + llvm::ArrayRef<DiagnosticRecord> diagtool::getBuiltinDiagnosticsByName() { return llvm::ArrayRef(BuiltinDiagnosticsByName); } -// FIXME: Is it worth having two tables, especially when this one can get -// out of sync easily? -static const DiagnosticRecord BuiltinDiagnosticsByID[] = { -#define DIAG(ENUM, CLASS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, SHOWINSYSMACRO, DEFER, CATEGORY, STABLE_ID, \ - LEGACY_STABLE_IDS) \ - {#ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t)}, -#include "clang/Basic/AllDiagnosticKinds.inc" -#undef DIAG -}; - -static bool orderByID(const DiagnosticRecord &Left, - const DiagnosticRecord &Right) { - return Left.DiagID < Right.DiagID; +static constexpr auto BuiltinDiagnosticIndexByID = [] { + std::array<uint16_t, diag::DIAG_UPPER_LIMIT> Result = {}; + uint16_t Index = 0; +#define DIAG_NAME_INDEX(ENUM) Result[diag::ENUM] = ++Index; +#include "clang/Basic/DiagnosticIndexName.inc" +#undef DIAG_NAME_INDEX + return Result; +}(); + +llvm::StringRef DiagnosticRecord::getName() const { + const char *Names = reinterpret_cast<const char *>(&BuiltinDiagnosticNames); + uint32_t NameOffset = + uint32_t(NameOffsetLow) | (uint32_t(NameOffsetHigh) << 16); + return llvm::StringRef(Names + NameOffset, NameLen); } const DiagnosticRecord &diagtool::getDiagnosticForID(short DiagID) { - DiagnosticRecord Key = {nullptr, DiagID, 0}; - - // The requirement for lower_bound to produce a valid result it is - // enough if the BuiltinDiagnosticsByID is partitioned (by DiagID), - // but as we want this function to work for all possible values of - // DiagID sent in as argument it is better to right away check if - // BuiltinDiagnosticsByID is sorted. - assert(llvm::is_sorted(BuiltinDiagnosticsByID, orderByID) && - "IDs in BuiltinDiagnosticsByID must be sorted."); - const DiagnosticRecord *Result = - llvm::lower_bound(BuiltinDiagnosticsByID, Key, orderByID); - assert(Result && "diagnostic not found; table may be out of date"); - return *Result; + assert(DiagID >= 0 && + static_cast<unsigned>(DiagID) < BuiltinDiagnosticIndexByID.size() && + BuiltinDiagnosticIndexByID[DiagID] != 0 && "diagnostic not found"); + return BuiltinDiagnosticsByName[BuiltinDiagnosticIndexByID[DiagID] - 1]; } - #define GET_DIAG_ARRAYS #include "clang/Basic/DiagnosticGroups.inc" #undef GET_DIAG_ARRAYS diff --git a/clang/tools/diagtool/DiagnosticNames.h b/clang/tools/diagtool/DiagnosticNames.h index f541e88577cc5a..52622875175af1 100644 --- a/clang/tools/diagtool/DiagnosticNames.h +++ b/clang/tools/diagtool/DiagnosticNames.h @@ -15,91 +15,84 @@ namespace diagtool { - struct DiagnosticRecord { - const char *NameStr; - short DiagID; - uint8_t NameLen; +struct DiagnosticRecord { + short DiagID; + uint16_t NameOffsetLow; + uint8_t NameOffsetHigh; + uint8_t NameLen; - llvm::StringRef getName() const { - return llvm::StringRef(NameStr, NameLen); + llvm::StringRef getName() const; + + bool operator<(const DiagnosticRecord &Other) const { + return getName() < Other.getName(); + } +}; +static_assert(sizeof(DiagnosticRecord) == 6, + "DiagnosticRecord must remain compact"); + +/// Get every diagnostic in the system, sorted by name. +llvm::ArrayRef<DiagnosticRecord> getBuiltinDiagnosticsByName(); + +/// Get a diagnostic by its ID. +const DiagnosticRecord &getDiagnosticForID(short DiagID); + +struct GroupRecord { + uint16_t NameOffset; + uint16_t Members; + uint16_t SubGroups; + + llvm::StringRef getName() const; + + template <typename RecordType> class group_iterator { + const short *CurrentID; + + friend struct GroupRecord; + group_iterator(const short *Start) : CurrentID(Start) { + if (CurrentID && *CurrentID == -1) + CurrentID = nullptr; } - bool operator<(const DiagnosticRecord &Other) const { - return getName() < Other.getName(); + public: + typedef RecordType value_type; + typedef const value_type &reference; + typedef const value_type *pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + inline reference operator*() const; + inline pointer operator->() const { return &operator*(); } + + inline short getID() const { return *CurrentID; } + + group_iterator &operator++() { + ++CurrentID; + if (*CurrentID == -1) + CurrentID = nullptr; + return *this; + } + + bool operator==(const group_iterator &Other) const { + return CurrentID == Other.CurrentID; } - }; - /// Get every diagnostic in the system, sorted by name. - llvm::ArrayRef<DiagnosticRecord> getBuiltinDiagnosticsByName(); - - /// Get a diagnostic by its ID. - const DiagnosticRecord &getDiagnosticForID(short DiagID); - - - struct GroupRecord { - uint16_t NameOffset; - uint16_t Members; - uint16_t SubGroups; - - llvm::StringRef getName() const; - - template<typename RecordType> - class group_iterator { - const short *CurrentID; - - friend struct GroupRecord; - group_iterator(const short *Start) : CurrentID(Start) { - if (CurrentID && *CurrentID == -1) - CurrentID = nullptr; - } - - public: - typedef RecordType value_type; - typedef const value_type & reference; - typedef const value_type * pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; - - inline reference operator*() const; - inline pointer operator->() const { - return &operator*(); - } - - inline short getID() const { - return *CurrentID; - } - - group_iterator &operator++() { - ++CurrentID; - if (*CurrentID == -1) - CurrentID = nullptr; - return *this; - } - - bool operator==(const group_iterator &Other) const { - return CurrentID == Other.CurrentID; - } - - bool operator!=(const group_iterator &Other) const { - return CurrentID != Other.CurrentID; - } - }; - - typedef group_iterator<GroupRecord> subgroup_iterator; - subgroup_iterator subgroup_begin() const; - subgroup_iterator subgroup_end() const; - llvm::iterator_range<subgroup_iterator> subgroups() const; - - typedef group_iterator<DiagnosticRecord> diagnostics_iterator; - diagnostics_iterator diagnostics_begin() const; - diagnostics_iterator diagnostics_end() const; - llvm::iterator_range<diagnostics_iterator> diagnostics() const; - - bool operator<(llvm::StringRef Other) const { - return getName() < Other; + bool operator!=(const group_iterator &Other) const { + return CurrentID != Other.CurrentID; } }; + typedef group_iterator<GroupRecord> subgroup_iterator; + subgroup_iterator subgroup_begin() const; + subgroup_iterator subgroup_end() const; + llvm::iterator_range<subgroup_iterator> subgroups() const; + + typedef group_iterator<DiagnosticRecord> diagnostics_iterator; + diagnostics_iterator diagnostics_begin() const; + diagnostics_iterator diagnostics_end() const; + llvm::iterator_range<diagnostics_iterator> diagnostics() const; + + bool operator<(llvm::StringRef Other) const { return getName() < Other; } +}; + /// Get every diagnostic group in the system, sorted by name. llvm::ArrayRef<GroupRecord> getDiagnosticGroups(); >From aefcb67df0e8753cd96b2332d9b1e1eb9de304bd Mon Sep 17 00:00:00 2001 From: David Zbarsky <[email protected]> Date: Wed, 8 Jul 2026 20:49:49 -0400 Subject: [PATCH 3/3] [clang] Refine StaticDiagInfoRec bit-field layout --- clang/lib/Basic/DiagnosticIDs.cpp | 9 +++++---- llvm/include/llvm/TableGen/StringToOffsetTable.h | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index 4485e6120a654c..f88851e7a8f480 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -79,14 +79,15 @@ struct StaticDiagInfoRec { uint16_t WarnNoWerror : 1; LLVM_PREFERRED_TYPE(bool) uint16_t WarnShowInSystemHeader : 1; - LLVM_PREFERRED_TYPE(diag::Group) - uint16_t OptionGroupIndex : 14; LLVM_PREFERRED_TYPE(bool) uint16_t WarnShowInSystemMacro : 1; + + LLVM_PREFERRED_TYPE(diag::Group) + uint16_t OptionGroupIndex : 14; LLVM_PREFERRED_TYPE(bool) uint16_t Deferrable : 1; - uint16_t DescriptionOffsetLow; + uint16_t DescriptionOffsetLow : 16; uint16_t DescriptionOffsetHigh : 4; uint16_t DescriptionLen : 12; @@ -173,8 +174,8 @@ const StaticDiagInfoRec StaticDiagInfo[] = { CATEGORY, \ NOWERROR, \ SHOWINSYSHEADER, \ - GROUP, \ SHOWINSYSMACRO, \ + GROUP, \ DEFERRABLE, \ uint16_t(DIAG_DESC_OFFSET_##ENUM), \ uint16_t(DIAG_DESC_OFFSET_##ENUM >> 16), \ diff --git a/llvm/include/llvm/TableGen/StringToOffsetTable.h b/llvm/include/llvm/TableGen/StringToOffsetTable.h index 159ef3639ea391..97020a08ffd124 100644 --- a/llvm/include/llvm/TableGen/StringToOffsetTable.h +++ b/llvm/include/llvm/TableGen/StringToOffsetTable.h @@ -71,7 +71,8 @@ class StringToOffsetTable { // // This preserves the large-string handling of EmitStringTableDef without // emitting an llvm::StringTable object. - void EmitStringTableStorageDef(raw_ostream &OS, const Twine &Name) const; + LLVM_ABI void EmitStringTableStorageDef(raw_ostream &OS, + const Twine &Name) const; // Emit the string as one single string. LLVM_ABI void EmitString(raw_ostream &O) const; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
