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