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 | |
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 Str; |
27 | } |
28 | |
29 | /// Returns the value of a specified key parsed from StringRef. |
30 | std::optional<int> Argument::getValAsInt() const { |
31 | APInt KeyVal; |
32 | if (Val.getAsInteger(Radix: 10, Result&: KeyVal)) |
33 | return std::nullopt; |
34 | return KeyVal.getSExtValue(); |
35 | } |
36 | |
37 | bool Argument::isValInt() const { return getValAsInt().has_value(); } |
38 | |
39 | void RemarkLocation::print(raw_ostream &OS) const { |
40 | OS << "{ " |
41 | << "File: "<< SourceFilePath << ", Line: "<< SourceLine |
42 | << " Column:"<< SourceColumn << " }\n"; |
43 | } |
44 | |
45 | void Argument::print(raw_ostream &OS) const { |
46 | OS << Key << ": "<< Val << "\n"; |
47 | } |
48 | |
49 | void Remark::print(raw_ostream &OS) const { |
50 | OS << "Name: "; |
51 | OS << RemarkName << "\n"; |
52 | OS << "Type: "<< typeToStr(Ty: 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). |
67 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(StringRef, LLVMRemarkStringRef) |
68 | |
69 | extern "C"const char *LLVMRemarkStringGetData(LLVMRemarkStringRef String) { |
70 | return unwrap(P: String)->data(); |
71 | } |
72 | |
73 | extern "C"uint32_t LLVMRemarkStringGetLen(LLVMRemarkStringRef String) { |
74 | return unwrap(P: String)->size(); |
75 | } |
76 | |
77 | extern "C"LLVMRemarkStringRef |
78 | LLVMRemarkDebugLocGetSourceFilePath(LLVMRemarkDebugLocRef DL) { |
79 | return wrap(P: &unwrap(P: DL)->SourceFilePath); |
80 | } |
81 | |
82 | extern "C"uint32_t LLVMRemarkDebugLocGetSourceLine(LLVMRemarkDebugLocRef DL) { |
83 | return unwrap(P: DL)->SourceLine; |
84 | } |
85 | |
86 | extern "C"uint32_t |
87 | LLVMRemarkDebugLocGetSourceColumn(LLVMRemarkDebugLocRef DL) { |
88 | return unwrap(P: DL)->SourceColumn; |
89 | } |
90 | |
91 | extern "C"LLVMRemarkStringRef LLVMRemarkArgGetKey(LLVMRemarkArgRef Arg) { |
92 | return wrap(P: &unwrap(P: Arg)->Key); |
93 | } |
94 | |
95 | extern "C"LLVMRemarkStringRef LLVMRemarkArgGetValue(LLVMRemarkArgRef Arg) { |
96 | return wrap(P: &unwrap(P: Arg)->Val); |
97 | } |
98 | |
99 | extern "C"LLVMRemarkDebugLocRef |
100 | LLVMRemarkArgGetDebugLoc(LLVMRemarkArgRef Arg) { |
101 | if (const std::optional<RemarkLocation> &Loc = unwrap(P: Arg)->Loc) |
102 | return wrap(P: &*Loc); |
103 | return nullptr; |
104 | } |
105 | |
106 | extern "C"void LLVMRemarkEntryDispose(LLVMRemarkEntryRef Remark) { |
107 | delete unwrap(P: Remark); |
108 | } |
109 | |
110 | extern "C"LLVMRemarkType LLVMRemarkEntryGetType(LLVMRemarkEntryRef Remark) { |
111 | // Assume here that the enums can be converted both ways. |
112 | return static_cast<LLVMRemarkType>(unwrap(P: Remark)->RemarkType); |
113 | } |
114 | |
115 | extern "C"LLVMRemarkStringRef |
116 | LLVMRemarkEntryGetPassName(LLVMRemarkEntryRef Remark) { |
117 | return wrap(P: &unwrap(P: Remark)->PassName); |
118 | } |
119 | |
120 | extern "C"LLVMRemarkStringRef |
121 | LLVMRemarkEntryGetRemarkName(LLVMRemarkEntryRef Remark) { |
122 | return wrap(P: &unwrap(P: Remark)->RemarkName); |
123 | } |
124 | |
125 | extern "C"LLVMRemarkStringRef |
126 | LLVMRemarkEntryGetFunctionName(LLVMRemarkEntryRef Remark) { |
127 | return wrap(P: &unwrap(P: Remark)->FunctionName); |
128 | } |
129 | |
130 | extern "C"LLVMRemarkDebugLocRef |
131 | LLVMRemarkEntryGetDebugLoc(LLVMRemarkEntryRef Remark) { |
132 | if (const std::optional<RemarkLocation> &Loc = unwrap(P: Remark)->Loc) |
133 | return wrap(P: &*Loc); |
134 | return nullptr; |
135 | } |
136 | |
137 | extern "C"uint64_t LLVMRemarkEntryGetHotness(LLVMRemarkEntryRef Remark) { |
138 | if (const std::optional<uint64_t> &Hotness = unwrap(P: Remark)->Hotness) |
139 | return *Hotness; |
140 | return 0; |
141 | } |
142 | |
143 | extern "C"uint32_t LLVMRemarkEntryGetNumArgs(LLVMRemarkEntryRef Remark) { |
144 | return unwrap(P: Remark)->Args.size(); |
145 | } |
146 | |
147 | extern "C"LLVMRemarkArgRef |
148 | LLVMRemarkEntryGetFirstArg(LLVMRemarkEntryRef Remark) { |
149 | ArrayRef<Argument> Args = unwrap(P: 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 | |
157 | extern "C"LLVMRemarkArgRef |
158 | LLVMRemarkEntryGetNextArg(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(x: It); |
165 | if (Next == unwrap(P: Remark)->Args.end()) |
166 | return nullptr; |
167 | |
168 | return reinterpret_cast<LLVMRemarkArgRef>(const_cast<Argument *>(Next)); |
169 | } |
170 |