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