DiagnosticInfos.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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 "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 16#include <llvm/ADT/StringRef.h> 17#include <llvm/Support/DataTypes.h> 18 19#include <algorithm> 20 21namespace mcld { 22 23namespace { 24 25struct DiagStaticInfo { 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 37 bool operator<(const DiagStaticInfo& pRHS) const { return (ID < pRHS.ID); } 38}; 39 40} // anonymous namespace 41 42static const DiagStaticInfo DiagCommonInfo[] = { 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] 54#undef DIAG 55 {0, DiagnosticEngine::None, 0, 0}}; 56 57static const unsigned int DiagCommonInfoSize = 58 sizeof(DiagCommonInfo) / sizeof(DiagCommonInfo[0]) - 1; 59 60static const DiagStaticInfo DiagLoCInfo[] = { 61#define DIAG(ENUM, CLASS, ADDRDESC, LOCDESC) \ 62 { diag::ENUM, CLASS, STR_SIZE(LOCDESC, uint16_t), LOCDESC } \ 63 , 64#include "mcld/LD/DiagAttribute.inc" // NOLINT [build/include] [4] 65#include "mcld/LD/DiagCommonKinds.inc" // NOLINT [build/include] [4] 66#include "mcld/LD/DiagReaders.inc" // NOLINT [build/include] [4] 67#include "mcld/LD/DiagSymbolResolutions.inc" // NOLINT [build/include] [4] 68#include "mcld/LD/DiagRelocations.inc" // NOLINT [build/include] [4] 69#include "mcld/LD/DiagLayouts.inc" // NOLINT [build/include] [4] 70#include "mcld/LD/DiagGOTPLT.inc" // NOLINT [build/include] [4] 71#include "mcld/LD/DiagLDScript.inc" // NOLINT [build/include] [4] 72#undef DIAG 73 {0, DiagnosticEngine::None, 0, 0}}; 74 75static const unsigned int DiagLoCInfoSize = 76 sizeof(DiagLoCInfo) / sizeof(DiagLoCInfo[0]) - 1; 77 78static const DiagStaticInfo* getDiagInfo(unsigned int pID, 79 bool pInLoC = false) { 80 const DiagStaticInfo* static_info = (pInLoC) ? DiagLoCInfo : DiagCommonInfo; 81 unsigned int info_size = (pInLoC) ? DiagLoCInfoSize : DiagCommonInfoSize; 82 83 DiagStaticInfo key = { 84 static_cast<uint16_t>(pID), DiagnosticEngine::None, 0, 0}; 85 86 const DiagStaticInfo* result = 87 std::lower_bound(static_info, static_info + info_size, key); 88 89 if (result == (static_info + info_size) || result->ID != pID) 90 return NULL; 91 92 return result; 93} 94 95//===----------------------------------------------------------------------===// 96// DiagnosticInfos 97//===----------------------------------------------------------------------===// 98DiagnosticInfos::DiagnosticInfos(const LinkerConfig& pConfig) 99 : m_Config(pConfig) { 100} 101 102DiagnosticInfos::~DiagnosticInfos() { 103} 104 105llvm::StringRef DiagnosticInfos::getDescription(unsigned int pID, 106 bool pInLoC) const { 107 return getDiagInfo(pID, pInLoC)->getDescription(); 108} 109 110bool DiagnosticInfos::process(DiagnosticEngine& pEngine) const { 111 Diagnostic info(pEngine); 112 113 unsigned int ID = info.getID(); 114 115 // we are not implement LineInfo, so keep pIsLoC false. 116 const DiagStaticInfo* static_info = getDiagInfo(ID); 117 118 DiagnosticEngine::Severity severity = static_info->Severity; 119 120 switch (ID) { 121 case diag::multiple_definitions: { 122 if (m_Config.options().isMulDefs()) { 123 severity = DiagnosticEngine::Ignore; 124 } 125 break; 126 } 127 case diag::undefined_reference: 128 case diag::undefined_reference_text: { 129 // we have not implement --unresolved-symbols=method yet. So far, MCLinker 130 // provides the easier --allow-shlib-undefined and --no-undefined (i.e. 131 // -z defs) 132 switch (m_Config.codeGenType()) { 133 case LinkerConfig::Object: 134 if (m_Config.options().isNoUndefined()) 135 severity = DiagnosticEngine::Error; 136 else 137 severity = DiagnosticEngine::Ignore; 138 break; 139 case LinkerConfig::DynObj: 140 if (m_Config.options().isNoUndefined()) 141 severity = DiagnosticEngine::Error; 142 else 143 severity = DiagnosticEngine::Ignore; 144 break; 145 default: 146 severity = DiagnosticEngine::Error; 147 break; 148 } 149 break; 150 } 151 case diag::debug_print_gc_sections: { 152 if (!m_Config.options().getPrintGCSections()) 153 severity = DiagnosticEngine::Ignore; 154 break; 155 } 156 default: 157 break; 158 } // end of switch 159 160 // If --fatal-warnings is turned on, then switch warnings and errors to fatal 161 if (m_Config.options().isFatalWarnings()) { 162 if (severity == DiagnosticEngine::Warning || 163 severity == DiagnosticEngine::Error) { 164 severity = DiagnosticEngine::Fatal; 165 } 166 } 167 168 // finally, report it. 169 pEngine.getPrinter()->handleDiagnostic(severity, info); 170 return true; 171} 172 173} // namespace mcld 174