DiagnosticInfos.cpp revision affc150dc44fab1911775a49636d0ce85333b634
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/MC/MCLDInfo.h> 14#include <mcld/LD/Diagnostic.h> 15#include <mcld/LD/DiagnosticInfos.h> 16#include <mcld/LD/DiagnosticPrinter.h> 17 18using namespace mcld; 19 20namespace { 21 22struct DiagStaticInfo 23{ 24public: 25 uint16_t ID; 26 DiagnosticEngine::Severity Severity; 27 uint16_t DescriptionLen; 28 const char* DescriptionStr; 29 30public: 31 llvm::StringRef getDescription() const 32 { return llvm::StringRef(DescriptionStr, DescriptionLen); } 33 34 bool operator<(const DiagStaticInfo& pRHS) const 35 { return (ID < pRHS.ID); } 36}; 37 38} // namespace anonymous 39 40static const DiagStaticInfo DiagCommonInfo[] = { 41#define DIAG(ENUM, CLASS, ADDRDESC, LOCDESC) \ 42 { diag::ENUM, CLASS, STR_SIZE(ADDRDESC, uint16_t), ADDRDESC }, 43#include "mcld/LD/DiagCommonKinds.inc" 44#include "mcld/LD/DiagReaders.inc" 45#include "mcld/LD/DiagSymbolResolutions.inc" 46#include "mcld/LD/DiagRelocations.inc" 47#include "mcld/LD/DiagLayouts.inc" 48#include "mcld/LD/DiagGOTPLT.inc" 49#undef DIAG 50 { 0, DiagnosticEngine::None, 0, 0} 51}; 52 53static const unsigned int DiagCommonInfoSize = 54 sizeof(DiagCommonInfo)/sizeof(DiagCommonInfo[0])-1; 55 56static const DiagStaticInfo DiagLoCInfo[] = { 57#define DIAG(ENUM, CLASS, ADDRDESC, LOCDESC) \ 58 { diag::ENUM, CLASS, STR_SIZE(LOCDESC, uint16_t), LOCDESC }, 59#include "mcld/LD/DiagReaders.inc" 60#include "mcld/LD/DiagSymbolResolutions.inc" 61#include "mcld/LD/DiagRelocations.inc" 62#include "mcld/LD/DiagLayouts.inc" 63#include "mcld/LD/DiagGOTPLT.inc" 64#undef DIAG 65 { 0, DiagnosticEngine::None, 0, 0} 66}; 67 68static const unsigned int DiagLoCInfoSize = 69 sizeof(DiagLoCInfo)/sizeof(DiagLoCInfo[0])-1; 70 71 72static const DiagStaticInfo* getDiagInfo(unsigned int pID, bool pInLoC = false) 73{ 74 const DiagStaticInfo* static_info = (pInLoC)?DiagLoCInfo:DiagCommonInfo; 75 unsigned int info_size = (pInLoC)?DiagLoCInfoSize:DiagCommonInfoSize; 76 77 DiagStaticInfo key = { static_cast<uint16_t>(pID), DiagnosticEngine::None, 0, 0 }; 78 const DiagStaticInfo *result = std::lower_bound(static_info, static_info + info_size, key); 79 80 if (result == (static_info + info_size) || result->ID != pID) 81 return NULL; 82 83 return result; 84} 85 86//===----------------------------------------------------------------------===// 87// DiagnosticInfos 88DiagnosticInfos::DiagnosticInfos(const MCLDInfo& pLDInfo) 89 : m_LDInfo(pLDInfo) { 90} 91 92DiagnosticInfos::~DiagnosticInfos() 93{ 94} 95 96llvm::StringRef DiagnosticInfos::getDescription(unsigned int pID, bool pInLoC) const 97{ 98 return getDiagInfo(pID, pInLoC)->getDescription(); 99} 100 101bool DiagnosticInfos::process(DiagnosticEngine& pEngine) const 102{ 103 Diagnostic info(pEngine); 104 105 unsigned int ID = info.getID(); 106 107 // we are not implement LineInfo, so keep pIsLoC false. 108 const DiagStaticInfo* static_info = getDiagInfo(ID); 109 110 DiagnosticEngine::Severity severity = static_info->Severity; 111 112 switch (ID) { 113 case diag::multiple_definitions: { 114 if (m_LDInfo.options().hasMulDefs()) { 115 severity = DiagnosticEngine::Ignore; 116 } 117 break; 118 } 119 case diag::undefined_reference: { 120 // we have not implement --unresolved-symbols=method yet. So far, MCLinker 121 // provides the easier --allow-shlib-undefined and --no-undefined (i.e. -z defs) 122 switch(m_LDInfo.output().type()) { 123 case Output::Object: 124 if (m_LDInfo.options().isNoUndefined()) 125 severity = DiagnosticEngine::Error; 126 else 127 severity = DiagnosticEngine::Ignore; 128 break; 129 case Output::DynObj: 130 if (m_LDInfo.options().isNoUndefined() || !m_LDInfo.options().isAllowShlibUndefined()) 131 severity = DiagnosticEngine::Error; 132 else 133 severity = DiagnosticEngine::Ignore; 134 break; 135 case Output::Exec: 136 severity = DiagnosticEngine::Error; 137 break; 138 } 139 break; 140 } 141 default: 142 break; 143 } // end of switch 144 145 // finally, report it. 146 pEngine.getPrinter()->handleDiagnostic(severity, info); 147 return true; 148} 149 150