DiagnosticInfos.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
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/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 55static const unsigned int DiagCommonInfoSize = 56 sizeof(DiagCommonInfo)/sizeof(DiagCommonInfo[0])-1; 57 58static 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 70static const unsigned int DiagLoCInfoSize = 71 sizeof(DiagLoCInfo)/sizeof(DiagLoCInfo[0])-1; 72 73 74static 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 90//===----------------------------------------------------------------------===// 91DiagnosticInfos::DiagnosticInfos(const LinkerConfig& pConfig) 92 : m_Config(pConfig) { 93} 94 95DiagnosticInfos::~DiagnosticInfos() 96{ 97} 98 99llvm::StringRef DiagnosticInfos::getDescription(unsigned int pID, bool pInLoC) const 100{ 101 return getDiagInfo(pID, pInLoC)->getDescription(); 102} 103 104bool 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: { 117 if (m_Config.options().hasMulDefs()) { 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) 125 switch(m_Config.codeGenType()) { 126 case LinkerConfig::Object: 127 if (m_Config.options().isNoUndefined()) 128 severity = DiagnosticEngine::Error; 129 else 130 severity = DiagnosticEngine::Ignore; 131 break; 132 case LinkerConfig::DynObj: 133 if (m_Config.options().isNoUndefined() || !m_Config.options().isAllowShlibUndefined()) 134 severity = DiagnosticEngine::Error; 135 else 136 severity = DiagnosticEngine::Ignore; 137 break; 138 case LinkerConfig::Exec: 139 default: 140 severity = DiagnosticEngine::Error; 141 break; 142 } 143 break; 144 } 145 default: 146 break; 147 } // end of switch 148 149 // If --fatal-warnings is turned on, then switch warnings and errors to fatal 150 if (m_Config.options().isFatalWarnings()) { 151 if (severity == DiagnosticEngine::Warning || 152 severity == DiagnosticEngine::Error) { 153 severity = DiagnosticEngine::Fatal; 154 } 155 } 156 157 // finally, report it. 158 pEngine.getPrinter()->handleDiagnostic(severity, info); 159 return true; 160} 161 162