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/ArrayRef.h" 15 #include <optional> 16 17 using namespace llvm; 18 using namespace llvm::remarks; 19 20 std::string Remark::getArgsAsMsg() const { 21 std::string Str; 22 raw_string_ostream OS(Str); 23 for (const Argument &Arg : Args) 24 OS << Arg.Val; 25 return OS.str(); 26 } 27 28 void RemarkLocation::print(raw_ostream &OS) const { 29 OS << "{ " 30 << "File: " << SourceFilePath << ", Line: " << SourceLine 31 << " Column:" << SourceColumn << " }\n"; 32 } 33 34 void Argument::print(raw_ostream &OS) const { 35 OS << Key << ": " << Val << "\n"; 36 } 37 38 void Remark::print(raw_ostream &OS) const { 39 OS << "Name: "; 40 OS << RemarkName << "\n"; 41 OS << "Type: " << typeToStr(RemarkType) << "\n"; 42 OS << "FunctionName: " << FunctionName << "\n"; 43 OS << "PassName: " << PassName << "\n"; 44 if (Loc) 45 OS << "Loc: " << Loc.value(); 46 if (Hotness) 47 OS << "Hotness: " << Hotness; 48 if (!Args.empty()) { 49 OS << "Args:\n"; 50 for (auto Arg : Args) 51 OS << "\t" << Arg; 52 } 53 } 54 55 // Create wrappers for C Binding types (see CBindingWrapping.h). 56 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(StringRef, LLVMRemarkStringRef) 57 58 extern "C" const char *LLVMRemarkStringGetData(LLVMRemarkStringRef String) { 59 return unwrap(String)->data(); 60 } 61 62 extern "C" uint32_t LLVMRemarkStringGetLen(LLVMRemarkStringRef String) { 63 return unwrap(String)->size(); 64 } 65 66 extern "C" LLVMRemarkStringRef 67 LLVMRemarkDebugLocGetSourceFilePath(LLVMRemarkDebugLocRef DL) { 68 return wrap(&unwrap(DL)->SourceFilePath); 69 } 70 71 extern "C" uint32_t LLVMRemarkDebugLocGetSourceLine(LLVMRemarkDebugLocRef DL) { 72 return unwrap(DL)->SourceLine; 73 } 74 75 extern "C" uint32_t 76 LLVMRemarkDebugLocGetSourceColumn(LLVMRemarkDebugLocRef DL) { 77 return unwrap(DL)->SourceColumn; 78 } 79 80 extern "C" LLVMRemarkStringRef LLVMRemarkArgGetKey(LLVMRemarkArgRef Arg) { 81 return wrap(&unwrap(Arg)->Key); 82 } 83 84 extern "C" LLVMRemarkStringRef LLVMRemarkArgGetValue(LLVMRemarkArgRef Arg) { 85 return wrap(&unwrap(Arg)->Val); 86 } 87 88 extern "C" LLVMRemarkDebugLocRef 89 LLVMRemarkArgGetDebugLoc(LLVMRemarkArgRef Arg) { 90 if (const std::optional<RemarkLocation> &Loc = unwrap(Arg)->Loc) 91 return wrap(&*Loc); 92 return nullptr; 93 } 94 95 extern "C" void LLVMRemarkEntryDispose(LLVMRemarkEntryRef Remark) { 96 delete unwrap(Remark); 97 } 98 99 extern "C" LLVMRemarkType LLVMRemarkEntryGetType(LLVMRemarkEntryRef Remark) { 100 // Assume here that the enums can be converted both ways. 101 return static_cast<LLVMRemarkType>(unwrap(Remark)->RemarkType); 102 } 103 104 extern "C" LLVMRemarkStringRef 105 LLVMRemarkEntryGetPassName(LLVMRemarkEntryRef Remark) { 106 return wrap(&unwrap(Remark)->PassName); 107 } 108 109 extern "C" LLVMRemarkStringRef 110 LLVMRemarkEntryGetRemarkName(LLVMRemarkEntryRef Remark) { 111 return wrap(&unwrap(Remark)->RemarkName); 112 } 113 114 extern "C" LLVMRemarkStringRef 115 LLVMRemarkEntryGetFunctionName(LLVMRemarkEntryRef Remark) { 116 return wrap(&unwrap(Remark)->FunctionName); 117 } 118 119 extern "C" LLVMRemarkDebugLocRef 120 LLVMRemarkEntryGetDebugLoc(LLVMRemarkEntryRef Remark) { 121 if (const std::optional<RemarkLocation> &Loc = unwrap(Remark)->Loc) 122 return wrap(&*Loc); 123 return nullptr; 124 } 125 126 extern "C" uint64_t LLVMRemarkEntryGetHotness(LLVMRemarkEntryRef Remark) { 127 if (const std::optional<uint64_t> &Hotness = unwrap(Remark)->Hotness) 128 return *Hotness; 129 return 0; 130 } 131 132 extern "C" uint32_t LLVMRemarkEntryGetNumArgs(LLVMRemarkEntryRef Remark) { 133 return unwrap(Remark)->Args.size(); 134 } 135 136 extern "C" LLVMRemarkArgRef 137 LLVMRemarkEntryGetFirstArg(LLVMRemarkEntryRef Remark) { 138 ArrayRef<Argument> Args = unwrap(Remark)->Args; 139 // No arguments to iterate on. 140 if (Args.empty()) 141 return nullptr; 142 return reinterpret_cast<LLVMRemarkArgRef>( 143 const_cast<Argument *>(Args.begin())); 144 } 145 146 extern "C" LLVMRemarkArgRef 147 LLVMRemarkEntryGetNextArg(LLVMRemarkArgRef ArgIt, LLVMRemarkEntryRef Remark) { 148 // No more arguments to iterate on. 149 if (ArgIt == nullptr) 150 return nullptr; 151 152 auto It = (ArrayRef<Argument>::const_iterator)ArgIt; 153 auto Next = std::next(It); 154 if (Next == unwrap(Remark)->Args.end()) 155 return nullptr; 156 157 return reinterpret_cast<LLVMRemarkArgRef>(const_cast<Argument *>(Next)); 158 } 159