DiagnosticInfos.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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 case LinkerConfig::Exec: 145 if (m_Config.options().isNoUndefined()) 146 severity = DiagnosticEngine::Error; 147 else 148 severity = DiagnosticEngine::Ignore; 149 break; 150 default: 151 severity = DiagnosticEngine::Error; 152 break; 153 } 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