1//===- Remark.cpp ---------------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// Implementation of the Remark type and the C API. 10// 11//===----------------------------------------------------------------------===// 12 13#include "llvm/Remarks/Remark.h" 14#include "llvm/ADT/APInt.h" 15#include "llvm/ADT/ArrayRef.h" 16#include <optional> 17 18using namespace llvm; 19using namespace llvm::remarks; 20 21std::string Remark::getArgsAsMsg() const { 22 std::string Str; 23 raw_string_ostream OS(Str); 24 for (const Argument &Arg : Args) 25 OS << Arg.Val; 26 return OS.str(); 27} 28 29/// Returns the value of a specified key parsed from StringRef. 30std::optional<int> Argument::getValAsInt() const { 31 APInt KeyVal; 32 if (Val.getAsInteger(10, KeyVal)) 33 return std::nullopt; 34 return KeyVal.getSExtValue(); 35} 36 37bool Argument::isValInt() const { return getValAsInt().has_value(); } 38 39void RemarkLocation::print(raw_ostream &OS) const { 40 OS << "{ " 41 << "File: " << SourceFilePath << ", Line: " << SourceLine 42 << " Column:" << SourceColumn << " }\n"; 43} 44 45void Argument::print(raw_ostream &OS) const { 46 OS << Key << ": " << Val << "\n"; 47} 48 49void Remark::print(raw_ostream &OS) const { 50 OS << "Name: "; 51 OS << RemarkName << "\n"; 52 OS << "Type: " << typeToStr(RemarkType) << "\n"; 53 OS << "FunctionName: " << FunctionName << "\n"; 54 OS << "PassName: " << PassName << "\n"; 55 if (Loc) 56 OS << "Loc: " << Loc.value(); 57 if (Hotness) 58 OS << "Hotness: " << Hotness; 59 if (!Args.empty()) { 60 OS << "Args:\n"; 61 for (auto Arg : Args) 62 OS << "\t" << Arg; 63 } 64} 65 66// Create wrappers for C Binding types (see CBindingWrapping.h). 67DEFINE_SIMPLE_CONVERSION_FUNCTIONS(StringRef, LLVMRemarkStringRef) 68 69extern "C" const char *LLVMRemarkStringGetData(LLVMRemarkStringRef String) { 70 return unwrap(String)->data(); 71} 72 73extern "C" uint32_t LLVMRemarkStringGetLen(LLVMRemarkStringRef String) { 74 return unwrap(String)->size(); 75} 76 77extern "C" LLVMRemarkStringRef 78LLVMRemarkDebugLocGetSourceFilePath(LLVMRemarkDebugLocRef DL) { 79 return wrap(&unwrap(DL)->SourceFilePath); 80} 81 82extern "C" uint32_t LLVMRemarkDebugLocGetSourceLine(LLVMRemarkDebugLocRef DL) { 83 return unwrap(DL)->SourceLine; 84} 85 86extern "C" uint32_t 87LLVMRemarkDebugLocGetSourceColumn(LLVMRemarkDebugLocRef DL) { 88 return unwrap(DL)->SourceColumn; 89} 90 91extern "C" LLVMRemarkStringRef LLVMRemarkArgGetKey(LLVMRemarkArgRef Arg) { 92 return wrap(&unwrap(Arg)->Key); 93} 94 95extern "C" LLVMRemarkStringRef LLVMRemarkArgGetValue(LLVMRemarkArgRef Arg) { 96 return wrap(&unwrap(Arg)->Val); 97} 98 99extern "C" LLVMRemarkDebugLocRef 100LLVMRemarkArgGetDebugLoc(LLVMRemarkArgRef Arg) { 101 if (const std::optional<RemarkLocation> &Loc = unwrap(Arg)->Loc) 102 return wrap(&*Loc); 103 return nullptr; 104} 105 106extern "C" void LLVMRemarkEntryDispose(LLVMRemarkEntryRef Remark) { 107 delete unwrap(Remark); 108} 109 110extern "C" LLVMRemarkType LLVMRemarkEntryGetType(LLVMRemarkEntryRef Remark) { 111 // Assume here that the enums can be converted both ways. 112 return static_cast<LLVMRemarkType>(unwrap(Remark)->RemarkType); 113} 114 115extern "C" LLVMRemarkStringRef 116LLVMRemarkEntryGetPassName(LLVMRemarkEntryRef Remark) { 117 return wrap(&unwrap(Remark)->PassName); 118} 119 120extern "C" LLVMRemarkStringRef 121LLVMRemarkEntryGetRemarkName(LLVMRemarkEntryRef Remark) { 122 return wrap(&unwrap(Remark)->RemarkName); 123} 124 125extern "C" LLVMRemarkStringRef 126LLVMRemarkEntryGetFunctionName(LLVMRemarkEntryRef Remark) { 127 return wrap(&unwrap(Remark)->FunctionName); 128} 129 130extern "C" LLVMRemarkDebugLocRef 131LLVMRemarkEntryGetDebugLoc(LLVMRemarkEntryRef Remark) { 132 if (const std::optional<RemarkLocation> &Loc = unwrap(Remark)->Loc) 133 return wrap(&*Loc); 134 return nullptr; 135} 136 137extern "C" uint64_t LLVMRemarkEntryGetHotness(LLVMRemarkEntryRef Remark) { 138 if (const std::optional<uint64_t> &Hotness = unwrap(Remark)->Hotness) 139 return *Hotness; 140 return 0; 141} 142 143extern "C" uint32_t LLVMRemarkEntryGetNumArgs(LLVMRemarkEntryRef Remark) { 144 return unwrap(Remark)->Args.size(); 145} 146 147extern "C" LLVMRemarkArgRef 148LLVMRemarkEntryGetFirstArg(LLVMRemarkEntryRef Remark) { 149 ArrayRef<Argument> Args = unwrap(Remark)->Args; 150 // No arguments to iterate on. 151 if (Args.empty()) 152 return nullptr; 153 return reinterpret_cast<LLVMRemarkArgRef>( 154 const_cast<Argument *>(Args.begin())); 155} 156 157extern "C" LLVMRemarkArgRef 158LLVMRemarkEntryGetNextArg(LLVMRemarkArgRef ArgIt, LLVMRemarkEntryRef Remark) { 159 // No more arguments to iterate on. 160 if (ArgIt == nullptr) 161 return nullptr; 162 163 auto It = (ArrayRef<Argument>::const_iterator)ArgIt; 164 auto Next = std::next(It); 165 if (Next == unwrap(Remark)->Args.end()) 166 return nullptr; 167 168 return reinterpret_cast<LLVMRemarkArgRef>(const_cast<Argument *>(Next)); 169} 170