DiagnosticInfos.cpp revision 0dea6bc96bb52346737966839ac68644f7939f58
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> 13#include <mcld/LinkerConfig.h> 14#include <mcld/LD/Diagnostic.h> 15#include <mcld/LD/DiagnosticInfos.h> 16#include <mcld/LD/DiagnosticPrinter.h> 17 18#include <algorithm> 19 20using namespace mcld; 21 22namespace { 23 24struct DiagStaticInfo 25{ 26public: 27 uint16_t ID; 28 DiagnosticEngine::Severity Severity; 29 uint16_t DescriptionLen; 30 const char* DescriptionStr; 31 32public: 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 42static const DiagStaticInfo DiagCommonInfo[] = { 43#define DIAG(ENUM, CLASS, ADDRDESC, LOCDESC) \ 44 { diag::ENUM, CLASS, STR_SIZE(ADDRDESC, uint16_t), ADDRDESC }, 45#include "mcld/LD/DiagAttribute.inc" 46#include "mcld/LD/DiagCommonKinds.inc" 47#include "mcld/LD/DiagReaders.inc" 48#include "mcld/LD/DiagSymbolResolutions.inc" 49#include "mcld/LD/DiagRelocations.inc" 50#include "mcld/LD/DiagLayouts.inc" 51#include "mcld/LD/DiagGOTPLT.inc" 52#include "mcld/LD/DiagLDScript.inc" 53#undef DIAG 54 { 0, DiagnosticEngine::None, 0, 0} 55}; 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#include "mcld/LD/DiagAttribute.inc" 64#include "mcld/LD/DiagCommonKinds.inc" 65#include "mcld/LD/DiagReaders.inc" 66#include "mcld/LD/DiagSymbolResolutions.inc" 67#include "mcld/LD/DiagRelocations.inc" 68#include "mcld/LD/DiagLayouts.inc" 69#include "mcld/LD/DiagGOTPLT.inc" 70#include "mcld/LD/DiagLDScript.inc" 71#undef DIAG 72 { 0, DiagnosticEngine::None, 0, 0} 73}; 74 75static const unsigned int DiagLoCInfoSize = 76 sizeof(DiagLoCInfo)/sizeof(DiagLoCInfo[0])-1; 77 78 79static const DiagStaticInfo* getDiagInfo(unsigned int pID, bool pInLoC = false) 80{ 81 const DiagStaticInfo* static_info = (pInLoC)?DiagLoCInfo:DiagCommonInfo; 82 unsigned int info_size = (pInLoC)?DiagLoCInfoSize:DiagCommonInfoSize; 83 84 DiagStaticInfo key = { static_cast<uint16_t>(pID), DiagnosticEngine::None, 0, 0 }; 85 const DiagStaticInfo *result = std::lower_bound(static_info, static_info + info_size, key); 86 87 if (result == (static_info + info_size) || result->ID != pID) 88 return NULL; 89 90 return result; 91} 92 93//===----------------------------------------------------------------------===// 94// DiagnosticInfos 95//===----------------------------------------------------------------------===// 96DiagnosticInfos::DiagnosticInfos(const LinkerConfig& pConfig) 97 : m_Config(pConfig) { 98} 99 100DiagnosticInfos::~DiagnosticInfos() 101{ 102} 103 104llvm::StringRef DiagnosticInfos::getDescription(unsigned int pID, bool pInLoC) const 105{ 106 return getDiagInfo(pID, pInLoC)->getDescription(); 107} 108 109bool DiagnosticInfos::process(DiagnosticEngine& pEngine) const 110{ 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. -z defs) 131 switch(m_Config.codeGenType()) { 132 case LinkerConfig::Object: 133 if (m_Config.options().isNoUndefined()) 134 severity = DiagnosticEngine::Error; 135 else 136 severity = DiagnosticEngine::Ignore; 137 break; 138 case LinkerConfig::DynObj: 139 if (m_Config.options().isNoUndefined()) 140 severity = DiagnosticEngine::Error; 141 else 142 severity = DiagnosticEngine::Ignore; 143 break; 144 default: 145 severity = DiagnosticEngine::Error; 146 break; 147 } 148 break; 149 } 150 case diag::debug_print_gc_sections: { 151 if (!m_Config.options().getPrintGCSections()) 152 severity = DiagnosticEngine::Ignore; 153 break; 154 } 155 default: 156 break; 157 } // end of switch 158 159 // If --fatal-warnings is turned on, then switch warnings and errors to fatal 160 if (m_Config.options().isFatalWarnings()) { 161 if (severity == DiagnosticEngine::Warning || 162 severity == DiagnosticEngine::Error) { 163 severity = DiagnosticEngine::Fatal; 164 } 165 } 166 167 // finally, report it. 168 pEngine.getPrinter()->handleDiagnostic(severity, info); 169 return true; 170} 171 172