Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 1 | //===- DiagnosticInfo.cpp -------------------------------------------------===// |
| 2 | // |
| 3 | // The MCLinker Project |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 9 | #include "mcld/LD/DiagnosticInfos.h" |
| 10 | |
| 11 | #include "mcld/LinkerConfig.h" |
| 12 | #include "mcld/ADT/SizeTraits.h" |
| 13 | #include "mcld/LD/Diagnostic.h" |
| 14 | #include "mcld/LD/DiagnosticPrinter.h" |
| 15 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 16 | #include <llvm/ADT/StringRef.h> |
| 17 | #include <llvm/Support/DataTypes.h> |
| 18 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 19 | #include <algorithm> |
| 20 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 21 | namespace mcld { |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 22 | |
| 23 | namespace { |
| 24 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 25 | struct DiagStaticInfo { |
| 26 | public: |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 27 | uint16_t ID; |
| 28 | DiagnosticEngine::Severity Severity; |
| 29 | uint16_t DescriptionLen; |
| 30 | const char* DescriptionStr; |
| 31 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 32 | public: |
| 33 | llvm::StringRef getDescription() const { |
| 34 | return llvm::StringRef(DescriptionStr, DescriptionLen); |
| 35 | } |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 36 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 37 | bool operator<(const DiagStaticInfo& pRHS) const { return (ID < pRHS.ID); } |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 38 | }; |
| 39 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 40 | } // anonymous namespace |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 41 | |
| 42 | static const DiagStaticInfo DiagCommonInfo[] = { |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 43 | #define DIAG(ENUM, CLASS, ADDRDESC, LOCDESC) \ |
| 44 | { diag::ENUM, CLASS, STR_SIZE(ADDRDESC, uint16_t), ADDRDESC } \ |
| 45 | , |
| 46 | #include "mcld/LD/DiagAttribute.inc" // NOLINT [build/include] [4] |
| 47 | #include "mcld/LD/DiagCommonKinds.inc" // NOLINT [build/include] [4] |
| 48 | #include "mcld/LD/DiagReaders.inc" // NOLINT [build/include] [4] |
| 49 | #include "mcld/LD/DiagSymbolResolutions.inc" // NOLINT [build/include] [4] |
| 50 | #include "mcld/LD/DiagRelocations.inc" // NOLINT [build/include] [4] |
| 51 | #include "mcld/LD/DiagLayouts.inc" // NOLINT [build/include] [4] |
| 52 | #include "mcld/LD/DiagGOTPLT.inc" // NOLINT [build/include] [4] |
| 53 | #include "mcld/LD/DiagLDScript.inc" // NOLINT [build/include] [4] |
Stephen Hines | cfcb224 | 2016-03-08 00:18:09 -0800 | [diff] [blame^] | 54 | #include "mcld/LD/DiagMips.inc" // NOLINT [build/include] [4] |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 55 | #undef DIAG |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 56 | {0, DiagnosticEngine::None, 0, 0}}; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 57 | |
| 58 | static const unsigned int DiagCommonInfoSize = |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 59 | sizeof(DiagCommonInfo) / sizeof(DiagCommonInfo[0]) - 1; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 60 | |
| 61 | static const DiagStaticInfo DiagLoCInfo[] = { |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 62 | #define DIAG(ENUM, CLASS, ADDRDESC, LOCDESC) \ |
| 63 | { diag::ENUM, CLASS, STR_SIZE(LOCDESC, uint16_t), LOCDESC } \ |
| 64 | , |
| 65 | #include "mcld/LD/DiagAttribute.inc" // NOLINT [build/include] [4] |
| 66 | #include "mcld/LD/DiagCommonKinds.inc" // NOLINT [build/include] [4] |
| 67 | #include "mcld/LD/DiagReaders.inc" // NOLINT [build/include] [4] |
| 68 | #include "mcld/LD/DiagSymbolResolutions.inc" // NOLINT [build/include] [4] |
| 69 | #include "mcld/LD/DiagRelocations.inc" // NOLINT [build/include] [4] |
| 70 | #include "mcld/LD/DiagLayouts.inc" // NOLINT [build/include] [4] |
| 71 | #include "mcld/LD/DiagGOTPLT.inc" // NOLINT [build/include] [4] |
| 72 | #include "mcld/LD/DiagLDScript.inc" // NOLINT [build/include] [4] |
Stephen Hines | cfcb224 | 2016-03-08 00:18:09 -0800 | [diff] [blame^] | 73 | #include "mcld/LD/DiagMips.inc" // NOLINT [build/include] [4] |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 74 | #undef DIAG |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 75 | {0, DiagnosticEngine::None, 0, 0}}; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 76 | |
| 77 | static const unsigned int DiagLoCInfoSize = |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 78 | sizeof(DiagLoCInfo) / sizeof(DiagLoCInfo[0]) - 1; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 79 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 80 | static const DiagStaticInfo* getDiagInfo(unsigned int pID, |
| 81 | bool pInLoC = false) { |
| 82 | const DiagStaticInfo* static_info = (pInLoC) ? DiagLoCInfo : DiagCommonInfo; |
| 83 | unsigned int info_size = (pInLoC) ? DiagLoCInfoSize : DiagCommonInfoSize; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 84 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 85 | DiagStaticInfo key = { |
| 86 | static_cast<uint16_t>(pID), DiagnosticEngine::None, 0, 0}; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 87 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 88 | const DiagStaticInfo* result = |
| 89 | std::lower_bound(static_info, static_info + info_size, key); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 90 | |
| 91 | if (result == (static_info + info_size) || result->ID != pID) |
| 92 | return NULL; |
| 93 | |
| 94 | return result; |
| 95 | } |
| 96 | |
| 97 | //===----------------------------------------------------------------------===// |
| 98 | // DiagnosticInfos |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 99 | //===----------------------------------------------------------------------===// |
| 100 | DiagnosticInfos::DiagnosticInfos(const LinkerConfig& pConfig) |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 101 | : m_Config(pConfig) { |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 102 | } |
| 103 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 104 | DiagnosticInfos::~DiagnosticInfos() { |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 105 | } |
| 106 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 107 | llvm::StringRef DiagnosticInfos::getDescription(unsigned int pID, |
| 108 | bool pInLoC) const { |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 109 | return getDiagInfo(pID, pInLoC)->getDescription(); |
| 110 | } |
| 111 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 112 | bool DiagnosticInfos::process(DiagnosticEngine& pEngine) const { |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 113 | Diagnostic info(pEngine); |
| 114 | |
| 115 | unsigned int ID = info.getID(); |
| 116 | |
| 117 | // we are not implement LineInfo, so keep pIsLoC false. |
| 118 | const DiagStaticInfo* static_info = getDiagInfo(ID); |
| 119 | |
| 120 | DiagnosticEngine::Severity severity = static_info->Severity; |
| 121 | |
| 122 | switch (ID) { |
| 123 | case diag::multiple_definitions: { |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 124 | if (m_Config.options().isMulDefs()) { |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 125 | severity = DiagnosticEngine::Ignore; |
| 126 | } |
| 127 | break; |
| 128 | } |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 129 | case diag::undefined_reference: |
| 130 | case diag::undefined_reference_text: { |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 131 | // we have not implement --unresolved-symbols=method yet. So far, MCLinker |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 132 | // provides the easier --allow-shlib-undefined and --no-undefined (i.e. |
| 133 | // -z defs) |
| 134 | switch (m_Config.codeGenType()) { |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 135 | case LinkerConfig::Object: |
| 136 | if (m_Config.options().isNoUndefined()) |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 137 | severity = DiagnosticEngine::Error; |
| 138 | else |
| 139 | severity = DiagnosticEngine::Ignore; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 140 | break; |
| 141 | case LinkerConfig::DynObj: |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 142 | if (m_Config.options().isNoUndefined()) |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 143 | severity = DiagnosticEngine::Error; |
| 144 | else |
| 145 | severity = DiagnosticEngine::Ignore; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 146 | break; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 147 | default: |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 148 | severity = DiagnosticEngine::Error; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 149 | break; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 150 | } |
| 151 | break; |
| 152 | } |
Stephen Hines | 0dea6bc | 2014-07-15 18:33:32 -0700 | [diff] [blame] | 153 | case diag::debug_print_gc_sections: { |
| 154 | if (!m_Config.options().getPrintGCSections()) |
| 155 | severity = DiagnosticEngine::Ignore; |
| 156 | break; |
| 157 | } |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 158 | default: |
| 159 | break; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 160 | } // end of switch |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 161 | |
Shih-wei Liao | d0fbbb2 | 2013-01-03 06:23:31 -0800 | [diff] [blame] | 162 | // If --fatal-warnings is turned on, then switch warnings and errors to fatal |
| 163 | if (m_Config.options().isFatalWarnings()) { |
| 164 | if (severity == DiagnosticEngine::Warning || |
| 165 | severity == DiagnosticEngine::Error) { |
| 166 | severity = DiagnosticEngine::Fatal; |
| 167 | } |
| 168 | } |
| 169 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 170 | // finally, report it. |
| 171 | pEngine.getPrinter()->handleDiagnostic(severity, info); |
| 172 | return true; |
| 173 | } |
| 174 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 175 | } // namespace mcld |