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