|
1 | 1 | #include "LLVMWrapper.h"
|
2 | 2 | #include "llvm/IR/DebugInfoMetadata.h"
|
| 3 | +#include "llvm/IR/DiagnosticHandler.h" |
3 | 4 | #include "llvm/IR/DiagnosticInfo.h"
|
4 | 5 | #include "llvm/IR/DiagnosticPrinter.h"
|
5 | 6 | #include "llvm/IR/GlobalVariable.h"
|
@@ -1177,10 +1178,13 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
|
1177 | 1178 | case DK_SampleProfile:
|
1178 | 1179 | return LLVMRustDiagnosticKind::SampleProfile;
|
1179 | 1180 | case DK_OptimizationRemark:
|
| 1181 | + case DK_MachineOptimizationRemark: |
1180 | 1182 | return LLVMRustDiagnosticKind::OptimizationRemark;
|
1181 | 1183 | case DK_OptimizationRemarkMissed:
|
| 1184 | + case DK_MachineOptimizationRemarkMissed: |
1182 | 1185 | return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
|
1183 | 1186 | case DK_OptimizationRemarkAnalysis:
|
| 1187 | + case DK_MachineOptimizationRemarkAnalysis: |
1184 | 1188 | return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
|
1185 | 1189 | case DK_OptimizationRemarkAnalysisFPCommute:
|
1186 | 1190 | return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
|
@@ -1783,3 +1787,92 @@ extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
|
1783 | 1787 | return LLVMRustResult::Success;
|
1784 | 1788 | }
|
1785 | 1789 | }
|
| 1790 | + |
| 1791 | +// Transfers ownership of DiagnosticHandler unique_ptr to the caller. |
| 1792 | +extern "C" DiagnosticHandler * |
| 1793 | +LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) { |
| 1794 | + std::unique_ptr<DiagnosticHandler> DH = unwrap(C)->getDiagnosticHandler(); |
| 1795 | + return DH.release(); |
| 1796 | +} |
| 1797 | + |
| 1798 | +// Sets unique_ptr to object of DiagnosticHandler to provide custom diagnostic |
| 1799 | +// handling. Ownership of the handler is moved to the LLVMContext. |
| 1800 | +extern "C" void LLVMRustContextSetDiagnosticHandler(LLVMContextRef C, |
| 1801 | + DiagnosticHandler *DH) { |
| 1802 | + unwrap(C)->setDiagnosticHandler(std::unique_ptr<DiagnosticHandler>(DH)); |
| 1803 | +} |
| 1804 | + |
| 1805 | +using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy; |
| 1806 | + |
| 1807 | +// Configures a diagnostic handler that invokes provided callback when a |
| 1808 | +// backend needs to emit a diagnostic. |
| 1809 | +// |
| 1810 | +// When RemarkAllPasses is true, remarks are enabled for all passes. Otherwise |
| 1811 | +// the RemarkPasses array specifies individual passes for which remarks will be |
| 1812 | +// enabled. |
| 1813 | +extern "C" void LLVMRustContextConfigureDiagnosticHandler( |
| 1814 | + LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback, |
| 1815 | + void *DiagnosticHandlerContext, bool RemarkAllPasses, |
| 1816 | + const char * const * RemarkPasses, size_t RemarkPassesLen) { |
| 1817 | + |
| 1818 | + class RustDiagnosticHandler final : public DiagnosticHandler { |
| 1819 | + public: |
| 1820 | + RustDiagnosticHandler(LLVMDiagnosticHandlerTy DiagnosticHandlerCallback, |
| 1821 | + void *DiagnosticHandlerContext, |
| 1822 | + bool RemarkAllPasses, |
| 1823 | + std::vector<std::string> RemarkPasses) |
| 1824 | + : DiagnosticHandlerCallback(DiagnosticHandlerCallback), |
| 1825 | + DiagnosticHandlerContext(DiagnosticHandlerContext), |
| 1826 | + RemarkAllPasses(RemarkAllPasses), |
| 1827 | + RemarkPasses(RemarkPasses) {} |
| 1828 | + |
| 1829 | + virtual bool handleDiagnostics(const DiagnosticInfo &DI) override { |
| 1830 | + if (DiagnosticHandlerCallback) { |
| 1831 | + DiagnosticHandlerCallback(DI, DiagnosticHandlerContext); |
| 1832 | + return true; |
| 1833 | + } |
| 1834 | + return false; |
| 1835 | + } |
| 1836 | + |
| 1837 | + bool isAnalysisRemarkEnabled(StringRef PassName) const override { |
| 1838 | + return isRemarkEnabled(PassName); |
| 1839 | + } |
| 1840 | + |
| 1841 | + bool isMissedOptRemarkEnabled(StringRef PassName) const override { |
| 1842 | + return isRemarkEnabled(PassName); |
| 1843 | + } |
| 1844 | + |
| 1845 | + bool isPassedOptRemarkEnabled(StringRef PassName) const override { |
| 1846 | + return isRemarkEnabled(PassName); |
| 1847 | + } |
| 1848 | + |
| 1849 | + bool isAnyRemarkEnabled() const override { |
| 1850 | + return RemarkAllPasses || !RemarkPasses.empty(); |
| 1851 | + } |
| 1852 | + |
| 1853 | + private: |
| 1854 | + bool isRemarkEnabled(StringRef PassName) const { |
| 1855 | + if (RemarkAllPasses) |
| 1856 | + return true; |
| 1857 | + |
| 1858 | + for (auto &Pass : RemarkPasses) |
| 1859 | + if (Pass == PassName) |
| 1860 | + return true; |
| 1861 | + |
| 1862 | + return false; |
| 1863 | + } |
| 1864 | + |
| 1865 | + LLVMDiagnosticHandlerTy DiagnosticHandlerCallback = nullptr; |
| 1866 | + void *DiagnosticHandlerContext = nullptr; |
| 1867 | + |
| 1868 | + bool RemarkAllPasses = false; |
| 1869 | + std::vector<std::string> RemarkPasses; |
| 1870 | + }; |
| 1871 | + |
| 1872 | + std::vector<std::string> Passes; |
| 1873 | + for (size_t I = 0; I != RemarkPassesLen; ++I) |
| 1874 | + Passes.push_back(RemarkPasses[I]); |
| 1875 | + |
| 1876 | + unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>( |
| 1877 | + DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes)); |
| 1878 | +} |
0 commit comments