Bug Summary

File:lib/ProfileData/Coverage/CoverageMappingReader.cpp
Warning:line 142, column 18
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name CoverageMappingReader.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/lib/ProfileData/Coverage -I /build/llvm-toolchain-snapshot-7~svn325874/lib/ProfileData/Coverage -I /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325874/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/lib/ProfileData/Coverage -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-23-163436-368-1 -x c++ /build/llvm-toolchain-snapshot-7~svn325874/lib/ProfileData/Coverage/CoverageMappingReader.cpp

/build/llvm-toolchain-snapshot-7~svn325874/lib/ProfileData/Coverage/CoverageMappingReader.cpp

1//===- CoverageMappingReader.cpp - Code coverage mapping reader -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for reading coverage mapping data for
11// instrumentation based coverage.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/ADT/Triple.h"
22#include "llvm/Object/Binary.h"
23#include "llvm/Object/Error.h"
24#include "llvm/Object/MachOUniversal.h"
25#include "llvm/Object/ObjectFile.h"
26#include "llvm/ProfileData/InstrProf.h"
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/Endian.h"
30#include "llvm/Support/Error.h"
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/LEB128.h"
33#include "llvm/Support/MathExtras.h"
34#include "llvm/Support/raw_ostream.h"
35#include <vector>
36
37using namespace llvm;
38using namespace coverage;
39using namespace object;
40
41#define DEBUG_TYPE"coverage-mapping" "coverage-mapping"
42
43void CoverageMappingIterator::increment() {
44 if (ReadErr != coveragemap_error::success)
45 return;
46
47 // Check if all the records were read or if an error occurred while reading
48 // the next record.
49 if (auto E = Reader->readNextRecord(Record))
50 handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
51 if (CME.get() == coveragemap_error::eof)
52 *this = CoverageMappingIterator();
53 else
54 ReadErr = CME.get();
55 });
56}
57
58Error RawCoverageReader::readULEB128(uint64_t &Result) {
59 if (Data.empty())
4
Assuming the condition is true
5
Taking true branch
60 return make_error<CoverageMapError>(coveragemap_error::truncated);
6
Calling 'make_error'
20
Returning from 'make_error'
61 unsigned N = 0;
62 Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
63 if (N > Data.size())
64 return make_error<CoverageMapError>(coveragemap_error::malformed);
65 Data = Data.substr(N);
66 return Error::success();
67}
68
69Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
70 if (auto Err = readULEB128(Result))
3
Calling 'RawCoverageReader::readULEB128'
21
Returning from 'RawCoverageReader::readULEB128'
22
Calling move constructor for 'Error'
46
Returning from move constructor for 'Error'
47
Calling 'Error::operator bool'
56
Returning from 'Error::operator bool'
57
Taking true branch
71 return Err;
58
Calling '~Error'
65
Returning from '~Error'
72 if (Result >= MaxPlus1)
73 return make_error<CoverageMapError>(coveragemap_error::malformed);
74 return Error::success();
75}
76
77Error RawCoverageReader::readSize(uint64_t &Result) {
78 if (auto Err = readULEB128(Result))
79 return Err;
80 // Sanity check the number.
81 if (Result > Data.size())
82 return make_error<CoverageMapError>(coveragemap_error::malformed);
83 return Error::success();
84}
85
86Error RawCoverageReader::readString(StringRef &Result) {
87 uint64_t Length;
88 if (auto Err = readSize(Length))
89 return Err;
90 Result = Data.substr(0, Length);
91 Data = Data.substr(Length);
92 return Error::success();
93}
94
95Error RawCoverageFilenamesReader::read() {
96 uint64_t NumFilenames;
97 if (auto Err = readSize(NumFilenames))
98 return Err;
99 for (size_t I = 0; I < NumFilenames; ++I) {
100 StringRef Filename;
101 if (auto Err = readString(Filename))
102 return Err;
103 Filenames.push_back(Filename);
104 }
105 return Error::success();
106}
107
108Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
109 auto Tag = Value & Counter::EncodingTagMask;
110 switch (Tag) {
111 case Counter::Zero:
112 C = Counter::getZero();
113 return Error::success();
114 case Counter::CounterValueReference:
115 C = Counter::getCounter(Value >> Counter::EncodingTagBits);
116 return Error::success();
117 default:
118 break;
119 }
120 Tag -= Counter::Expression;
121 switch (Tag) {
122 case CounterExpression::Subtract:
123 case CounterExpression::Add: {
124 auto ID = Value >> Counter::EncodingTagBits;
125 if (ID >= Expressions.size())
126 return make_error<CoverageMapError>(coveragemap_error::malformed);
127 Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
128 C = Counter::getExpression(ID);
129 break;
130 }
131 default:
132 return make_error<CoverageMapError>(coveragemap_error::malformed);
133 }
134 return Error::success();
135}
136
137Error RawCoverageMappingReader::readCounter(Counter &C) {
138 uint64_t EncodedCounter;
1
'EncodedCounter' declared without an initial value
139 if (auto Err =
67
Taking false branch
140 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
2
Calling 'RawCoverageReader::readIntMax'
66
Returning from 'RawCoverageReader::readIntMax'
141 return Err;
142 if (auto Err = decodeCounter(EncodedCounter, C))
68
1st function call argument is an uninitialized value
143 return Err;
144 return Error::success();
145}
146
147static const unsigned EncodingExpansionRegionBit = 1
148 << Counter::EncodingTagBits;
149
150/// \brief Read the sub-array of regions for the given inferred file id.
151/// \param NumFileIDs the number of file ids that are defined for this
152/// function.
153Error RawCoverageMappingReader::readMappingRegionsSubArray(
154 std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
155 size_t NumFileIDs) {
156 uint64_t NumRegions;
157 if (auto Err = readSize(NumRegions))
158 return Err;
159 unsigned LineStart = 0;
160 for (size_t I = 0; I < NumRegions; ++I) {
161 Counter C;
162 CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
163
164 // Read the combined counter + region kind.
165 uint64_t EncodedCounterAndRegion;
166 if (auto Err = readIntMax(EncodedCounterAndRegion,
167 std::numeric_limits<unsigned>::max()))
168 return Err;
169 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
170 uint64_t ExpandedFileID = 0;
171 if (Tag != Counter::Zero) {
172 if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
173 return Err;
174 } else {
175 // Is it an expansion region?
176 if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
177 Kind = CounterMappingRegion::ExpansionRegion;
178 ExpandedFileID = EncodedCounterAndRegion >>
179 Counter::EncodingCounterTagAndExpansionRegionTagBits;
180 if (ExpandedFileID >= NumFileIDs)
181 return make_error<CoverageMapError>(coveragemap_error::malformed);
182 } else {
183 switch (EncodedCounterAndRegion >>
184 Counter::EncodingCounterTagAndExpansionRegionTagBits) {
185 case CounterMappingRegion::CodeRegion:
186 // Don't do anything when we have a code region with a zero counter.
187 break;
188 case CounterMappingRegion::SkippedRegion:
189 Kind = CounterMappingRegion::SkippedRegion;
190 break;
191 default:
192 return make_error<CoverageMapError>(coveragemap_error::malformed);
193 }
194 }
195 }
196
197 // Read the source range.
198 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
199 if (auto Err =
200 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
201 return Err;
202 if (auto Err = readULEB128(ColumnStart))
203 return Err;
204 if (ColumnStart > std::numeric_limits<unsigned>::max())
205 return make_error<CoverageMapError>(coveragemap_error::malformed);
206 if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
207 return Err;
208 if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
209 return Err;
210 LineStart += LineStartDelta;
211
212 // If the high bit of ColumnEnd is set, this is a gap region.
213 if (ColumnEnd & (1U << 31)) {
214 Kind = CounterMappingRegion::GapRegion;
215 ColumnEnd &= ~(1U << 31);
216 }
217
218 // Adjust the column locations for the empty regions that are supposed to
219 // cover whole lines. Those regions should be encoded with the
220 // column range (1 -> std::numeric_limits<unsigned>::max()), but because
221 // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
222 // we set the column range to (0 -> 0) to ensure that the column start and
223 // column end take up one byte each.
224 // The std::numeric_limits<unsigned>::max() is used to represent a column
225 // position at the end of the line without knowing the length of that line.
226 if (ColumnStart == 0 && ColumnEnd == 0) {
227 ColumnStart = 1;
228 ColumnEnd = std::numeric_limits<unsigned>::max();
229 }
230
231 DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
232 dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
233 << ColumnStart << " -> " << (LineStart + NumLines) << ":"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
234 << ColumnEnd << ", ";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
235 if (Kind == CounterMappingRegion::ExpansionRegion)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
236 dbgs() << "Expands to file " << ExpandedFileID;do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
237 elsedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
238 CounterMappingContext(Expressions).dump(C, dbgs());do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
239 dbgs() << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
240 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("coverage-mapping")) { { dbgs() << "Counter in file " <<
InferredFileID << " " << LineStart << ":" <<
ColumnStart << " -> " << (LineStart + NumLines
) << ":" << ColumnEnd << ", "; if (Kind == CounterMappingRegion
::ExpansionRegion) dbgs() << "Expands to file " <<
ExpandedFileID; else CounterMappingContext(Expressions).dump
(C, dbgs()); dbgs() << "\n"; }; } } while (false)
;
241
242 auto CMR = CounterMappingRegion(C, InferredFileID, ExpandedFileID,
243 LineStart, ColumnStart,
244 LineStart + NumLines, ColumnEnd, Kind);
245 if (CMR.startLoc() > CMR.endLoc())
246 return make_error<CoverageMapError>(coveragemap_error::malformed);
247 MappingRegions.push_back(CMR);
248 }
249 return Error::success();
250}
251
252Error RawCoverageMappingReader::read() {
253 // Read the virtual file mapping.
254 SmallVector<unsigned, 8> VirtualFileMapping;
255 uint64_t NumFileMappings;
256 if (auto Err = readSize(NumFileMappings))
257 return Err;
258 for (size_t I = 0; I < NumFileMappings; ++I) {
259 uint64_t FilenameIndex;
260 if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
261 return Err;
262 VirtualFileMapping.push_back(FilenameIndex);
263 }
264
265 // Construct the files using unique filenames and virtual file mapping.
266 for (auto I : VirtualFileMapping) {
267 Filenames.push_back(TranslationUnitFilenames[I]);
268 }
269
270 // Read the expressions.
271 uint64_t NumExpressions;
272 if (auto Err = readSize(NumExpressions))
273 return Err;
274 // Create an array of dummy expressions that get the proper counters
275 // when the expressions are read, and the proper kinds when the counters
276 // are decoded.
277 Expressions.resize(
278 NumExpressions,
279 CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
280 for (size_t I = 0; I < NumExpressions; ++I) {
281 if (auto Err = readCounter(Expressions[I].LHS))
282 return Err;
283 if (auto Err = readCounter(Expressions[I].RHS))
284 return Err;
285 }
286
287 // Read the mapping regions sub-arrays.
288 for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
289 InferredFileID < S; ++InferredFileID) {
290 if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
291 VirtualFileMapping.size()))
292 return Err;
293 }
294
295 // Set the counters for the expansion regions.
296 // i.e. Counter of expansion region = counter of the first region
297 // from the expanded file.
298 // Perform multiple passes to correctly propagate the counters through
299 // all the nested expansion regions.
300 SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
301 FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
302 for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
303 for (auto &R : MappingRegions) {
304 if (R.Kind != CounterMappingRegion::ExpansionRegion)
305 continue;
306 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID])(static_cast <bool> (!FileIDExpansionRegionMapping[R.ExpandedFileID
]) ? void (0) : __assert_fail ("!FileIDExpansionRegionMapping[R.ExpandedFileID]"
, "/build/llvm-toolchain-snapshot-7~svn325874/lib/ProfileData/Coverage/CoverageMappingReader.cpp"
, 306, __extension__ __PRETTY_FUNCTION__))
;
307 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
308 }
309 for (auto &R : MappingRegions) {
310 if (FileIDExpansionRegionMapping[R.FileID]) {
311 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
312 FileIDExpansionRegionMapping[R.FileID] = nullptr;
313 }
314 }
315 }
316
317 return Error::success();
318}
319
320Expected<bool> RawCoverageMappingDummyChecker::isDummy() {
321 // A dummy coverage mapping data consists of just one region with zero count.
322 uint64_t NumFileMappings;
323 if (Error Err = readSize(NumFileMappings))
324 return std::move(Err);
325 if (NumFileMappings != 1)
326 return false;
327 // We don't expect any specific value for the filename index, just skip it.
328 uint64_t FilenameIndex;
329 if (Error Err =
330 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
331 return std::move(Err);
332 uint64_t NumExpressions;
333 if (Error Err = readSize(NumExpressions))
334 return std::move(Err);
335 if (NumExpressions != 0)
336 return false;
337 uint64_t NumRegions;
338 if (Error Err = readSize(NumRegions))
339 return std::move(Err);
340 if (NumRegions != 1)
341 return false;
342 uint64_t EncodedCounterAndRegion;
343 if (Error Err = readIntMax(EncodedCounterAndRegion,
344 std::numeric_limits<unsigned>::max()))
345 return std::move(Err);
346 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
347 return Tag == Counter::Zero;
348}
349
350Error InstrProfSymtab::create(SectionRef &Section) {
351 if (auto EC = Section.getContents(Data))
352 return errorCodeToError(EC);
353 Address = Section.getAddress();
354 return Error::success();
355}
356
357StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
358 if (Pointer < Address)
359 return StringRef();
360 auto Offset = Pointer - Address;
361 if (Offset + Size > Data.size())
362 return StringRef();
363 return Data.substr(Pointer - Address, Size);
364}
365
366// Check if the mapping data is a dummy, i.e. is emitted for an unused function.
367static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
368 // The hash value of dummy mapping records is always zero.
369 if (Hash)
370 return false;
371 return RawCoverageMappingDummyChecker(Mapping).isDummy();
372}
373
374namespace {
375
376struct CovMapFuncRecordReader {
377 virtual ~CovMapFuncRecordReader() = default;
378
379 // The interface to read coverage mapping function records for a module.
380 //
381 // \p Buf points to the buffer containing the \c CovHeader of the coverage
382 // mapping data associated with the module.
383 //
384 // Returns a pointer to the next \c CovHeader if it exists, or a pointer
385 // greater than \p End if not.
386 virtual Expected<const char *> readFunctionRecords(const char *Buf,
387 const char *End) = 0;
388
389 template <class IntPtrT, support::endianness Endian>
390 static Expected<std::unique_ptr<CovMapFuncRecordReader>>
391 get(CovMapVersion Version, InstrProfSymtab &P,
392 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
393 std::vector<StringRef> &F);
394};
395
396// A class for reading coverage mapping function records for a module.
397template <CovMapVersion Version, class IntPtrT, support::endianness Endian>
398class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
399 using FuncRecordType =
400 typename CovMapTraits<Version, IntPtrT>::CovMapFuncRecordType;
401 using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
402
403 // Maps function's name references to the indexes of their records
404 // in \c Records.
405 DenseMap<NameRefType, size_t> FunctionRecords;
406 InstrProfSymtab &ProfileNames;
407 std::vector<StringRef> &Filenames;
408 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
409
410 // Add the record to the collection if we don't already have a record that
411 // points to the same function name. This is useful to ignore the redundant
412 // records for the functions with ODR linkage.
413 // In addition, prefer records with real coverage mapping data to dummy
414 // records, which were emitted for inline functions which were seen but
415 // not used in the corresponding translation unit.
416 Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
417 StringRef Mapping, size_t FilenamesBegin) {
418 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
419 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
420 auto InsertResult =
421 FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
422 if (InsertResult.second) {
423 StringRef FuncName;
424 if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
425 return Err;
426 if (FuncName.empty())
427 return make_error<InstrProfError>(instrprof_error::malformed);
428 Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
429 Filenames.size() - FilenamesBegin);
430 return Error::success();
431 }
432 // Update the existing record if it's a dummy and the new record is real.
433 size_t OldRecordIndex = InsertResult.first->second;
434 BinaryCoverageReader::ProfileMappingRecord &OldRecord =
435 Records[OldRecordIndex];
436 Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
437 OldRecord.FunctionHash, OldRecord.CoverageMapping);
438 if (Error Err = OldIsDummyExpected.takeError())
439 return Err;
440 if (!*OldIsDummyExpected)
441 return Error::success();
442 Expected<bool> NewIsDummyExpected =
443 isCoverageMappingDummy(FuncHash, Mapping);
444 if (Error Err = NewIsDummyExpected.takeError())
445 return Err;
446 if (*NewIsDummyExpected)
447 return Error::success();
448 OldRecord.FunctionHash = FuncHash;
449 OldRecord.CoverageMapping = Mapping;
450 OldRecord.FilenamesBegin = FilenamesBegin;
451 OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin;
452 return Error::success();
453 }
454
455public:
456 VersionedCovMapFuncRecordReader(
457 InstrProfSymtab &P,
458 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
459 std::vector<StringRef> &F)
460 : ProfileNames(P), Filenames(F), Records(R) {}
461
462 ~VersionedCovMapFuncRecordReader() override = default;
463
464 Expected<const char *> readFunctionRecords(const char *Buf,
465 const char *End) override {
466 using namespace support;
467
468 if (Buf + sizeof(CovMapHeader) > End)
469 return make_error<CoverageMapError>(coveragemap_error::malformed);
470 auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);
471 uint32_t NRecords = CovHeader->getNRecords<Endian>();
472 uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
473 uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
474 assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version)(static_cast <bool> ((CovMapVersion)CovHeader->getVersion
<Endian>() == Version) ? void (0) : __assert_fail ("(CovMapVersion)CovHeader->getVersion<Endian>() == Version"
, "/build/llvm-toolchain-snapshot-7~svn325874/lib/ProfileData/Coverage/CoverageMappingReader.cpp"
, 474, __extension__ __PRETTY_FUNCTION__))
;
475 Buf = reinterpret_cast<const char *>(CovHeader + 1);
476
477 // Skip past the function records, saving the start and end for later.
478 const char *FunBuf = Buf;
479 Buf += NRecords * sizeof(FuncRecordType);
480 const char *FunEnd = Buf;
481
482 // Get the filenames.
483 if (Buf + FilenamesSize > End)
484 return make_error<CoverageMapError>(coveragemap_error::malformed);
485 size_t FilenamesBegin = Filenames.size();
486 RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
487 if (auto Err = Reader.read())
488 return std::move(Err);
489 Buf += FilenamesSize;
490
491 // We'll read the coverage mapping records in the loop below.
492 const char *CovBuf = Buf;
493 Buf += CoverageSize;
494 const char *CovEnd = Buf;
495
496 if (Buf > End)
497 return make_error<CoverageMapError>(coveragemap_error::malformed);
498 // Each coverage map has an alignment of 8, so we need to adjust alignment
499 // before reading the next map.
500 Buf += alignmentAdjustment(Buf, 8);
501
502 auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
503 while ((const char *)CFR < FunEnd) {
504 // Read the function information
505 uint32_t DataSize = CFR->template getDataSize<Endian>();
506
507 // Now use that to read the coverage data.
508 if (CovBuf + DataSize > CovEnd)
509 return make_error<CoverageMapError>(coveragemap_error::malformed);
510 auto Mapping = StringRef(CovBuf, DataSize);
511 CovBuf += DataSize;
512
513 if (Error Err =
514 insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
515 return std::move(Err);
516 CFR++;
517 }
518 return Buf;
519 }
520};
521
522} // end anonymous namespace
523
524template <class IntPtrT, support::endianness Endian>
525Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
526 CovMapVersion Version, InstrProfSymtab &P,
527 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
528 std::vector<StringRef> &F) {
529 using namespace coverage;
530
531 switch (Version) {
532 case CovMapVersion::Version1:
533 return llvm::make_unique<VersionedCovMapFuncRecordReader<
534 CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
535 case CovMapVersion::Version2:
536 case CovMapVersion::Version3:
537 // Decompress the name data.
538 if (Error E = P.create(P.getNameData()))
539 return std::move(E);
540 if (Version == CovMapVersion::Version2)
541 return llvm::make_unique<VersionedCovMapFuncRecordReader<
542 CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
543 else
544 return llvm::make_unique<VersionedCovMapFuncRecordReader<
545 CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
546 }
547 llvm_unreachable("Unsupported version")::llvm::llvm_unreachable_internal("Unsupported version", "/build/llvm-toolchain-snapshot-7~svn325874/lib/ProfileData/Coverage/CoverageMappingReader.cpp"
, 547)
;
548}
549
550template <typename T, support::endianness Endian>
551static Error readCoverageMappingData(
552 InstrProfSymtab &ProfileNames, StringRef Data,
553 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
554 std::vector<StringRef> &Filenames) {
555 using namespace coverage;
556
557 // Read the records in the coverage data section.
558 auto CovHeader =
559 reinterpret_cast<const CovMapHeader *>(Data.data());
560 CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
561 if (Version > CovMapVersion::CurrentVersion)
562 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
563 Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
564 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
565 Filenames);
566 if (Error E = ReaderExpected.takeError())
567 return E;
568 auto Reader = std::move(ReaderExpected.get());
569 for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
570 auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End);
571 if (auto E = NextHeaderOrErr.takeError())
572 return E;
573 Buf = NextHeaderOrErr.get();
574 }
575 return Error::success();
576}
577
578static const char *TestingFormatMagic = "llvmcovmtestdata";
579
580static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames,
581 StringRef &CoverageMapping,
582 uint8_t &BytesInAddress,
583 support::endianness &Endian) {
584 BytesInAddress = 8;
585 Endian = support::endianness::little;
586
587 Data = Data.substr(StringRef(TestingFormatMagic).size());
588 if (Data.empty())
589 return make_error<CoverageMapError>(coveragemap_error::truncated);
590 unsigned N = 0;
591 auto ProfileNamesSize =
592 decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
593 if (N > Data.size())
594 return make_error<CoverageMapError>(coveragemap_error::malformed);
595 Data = Data.substr(N);
596 if (Data.empty())
597 return make_error<CoverageMapError>(coveragemap_error::truncated);
598 N = 0;
599 uint64_t Address =
600 decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
601 if (N > Data.size())
602 return make_error<CoverageMapError>(coveragemap_error::malformed);
603 Data = Data.substr(N);
604 if (Data.size() < ProfileNamesSize)
605 return make_error<CoverageMapError>(coveragemap_error::malformed);
606 if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
607 return E;
608 CoverageMapping = Data.substr(ProfileNamesSize);
609 // Skip the padding bytes because coverage map data has an alignment of 8.
610 if (CoverageMapping.empty())
611 return make_error<CoverageMapError>(coveragemap_error::truncated);
612 size_t Pad = alignmentAdjustment(CoverageMapping.data(), 8);
613 if (CoverageMapping.size() < Pad)
614 return make_error<CoverageMapError>(coveragemap_error::malformed);
615 CoverageMapping = CoverageMapping.substr(Pad);
616 return Error::success();
617}
618
619static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
620 StringRef FoundName;
621 for (const auto &Section : OF.sections()) {
622 if (auto EC = Section.getName(FoundName))
623 return errorCodeToError(EC);
624 if (FoundName == Name)
625 return Section;
626 }
627 return make_error<CoverageMapError>(coveragemap_error::no_data_found);
628}
629
630static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
631 InstrProfSymtab &ProfileNames,
632 StringRef &CoverageMapping,
633 uint8_t &BytesInAddress,
634 support::endianness &Endian, StringRef Arch) {
635 auto BinOrErr = createBinary(ObjectBuffer);
636 if (!BinOrErr)
637 return BinOrErr.takeError();
638 auto Bin = std::move(BinOrErr.get());
639 std::unique_ptr<ObjectFile> OF;
640 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
641 // If we have a universal binary, try to look up the object for the
642 // appropriate architecture.
643 auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
644 if (!ObjectFileOrErr)
645 return ObjectFileOrErr.takeError();
646 OF = std::move(ObjectFileOrErr.get());
647 } else if (isa<ObjectFile>(Bin.get())) {
648 // For any other object file, upcast and take ownership.
649 OF.reset(cast<ObjectFile>(Bin.release()));
650 // If we've asked for a particular arch, make sure they match.
651 if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
652 return errorCodeToError(object_error::arch_not_found);
653 } else
654 // We can only handle object files.
655 return make_error<CoverageMapError>(coveragemap_error::malformed);
656
657 // The coverage uses native pointer sizes for the object it's written in.
658 BytesInAddress = OF->getBytesInAddress();
659 Endian = OF->isLittleEndian() ? support::endianness::little
660 : support::endianness::big;
661
662 // Look for the sections that we are interested in.
663 auto ObjFormat = OF->getTripleObjectFormat();
664 auto NamesSection =
665 lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
666 /*AddSegmentInfo=*/false));
667 if (auto E = NamesSection.takeError())
668 return E;
669 auto CoverageSection =
670 lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
671 /*AddSegmentInfo=*/false));
672 if (auto E = CoverageSection.takeError())
673 return E;
674
675 // Get the contents of the given sections.
676 if (auto EC = CoverageSection->getContents(CoverageMapping))
677 return errorCodeToError(EC);
678 if (Error E = ProfileNames.create(*NamesSection))
679 return E;
680
681 return Error::success();
682}
683
684Expected<std::unique_ptr<BinaryCoverageReader>>
685BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
686 StringRef Arch) {
687 std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
688
689 StringRef Coverage;
690 uint8_t BytesInAddress;
691 support::endianness Endian;
692 Error E = Error::success();
693 consumeError(std::move(E));
694 if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
695 // This is a special format used for testing.
696 E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
697 Coverage, BytesInAddress, Endian);
698 else
699 E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
700 Coverage, BytesInAddress, Endian, Arch);
701 if (E)
702 return std::move(E);
703
704 if (BytesInAddress == 4 && Endian == support::endianness::little)
705 E = readCoverageMappingData<uint32_t, support::endianness::little>(
706 Reader->ProfileNames, Coverage, Reader->MappingRecords,
707 Reader->Filenames);
708 else if (BytesInAddress == 4 && Endian == support::endianness::big)
709 E = readCoverageMappingData<uint32_t, support::endianness::big>(
710 Reader->ProfileNames, Coverage, Reader->MappingRecords,
711 Reader->Filenames);
712 else if (BytesInAddress == 8 && Endian == support::endianness::little)
713 E = readCoverageMappingData<uint64_t, support::endianness::little>(
714 Reader->ProfileNames, Coverage, Reader->MappingRecords,
715 Reader->Filenames);
716 else if (BytesInAddress == 8 && Endian == support::endianness::big)
717 E = readCoverageMappingData<uint64_t, support::endianness::big>(
718 Reader->ProfileNames, Coverage, Reader->MappingRecords,
719 Reader->Filenames);
720 else
721 return make_error<CoverageMapError>(coveragemap_error::malformed);
722 if (E)
723 return std::move(E);
724 return std::move(Reader);
725}
726
727Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
728 if (CurrentRecord >= MappingRecords.size())
729 return make_error<CoverageMapError>(coveragemap_error::eof);
730
731 FunctionsFilenames.clear();
732 Expressions.clear();
733 MappingRegions.clear();
734 auto &R = MappingRecords[CurrentRecord];
735 RawCoverageMappingReader Reader(
736 R.CoverageMapping,
737 makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
738 FunctionsFilenames, Expressions, MappingRegions);
739 if (auto Err = Reader.read())
740 return Err;
741
742 Record.FunctionName = R.FunctionName;
743 Record.FunctionHash = R.FunctionHash;
744 Record.Filenames = FunctionsFilenames;
745 Record.Expressions = Expressions;
746 Record.MappingRegions = MappingRegions;
747
748 ++CurrentRecord;
749 return Error::success();
750}

/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h

1//===- llvm/Support/Error.h - Recoverable error handling --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an API used to report recoverable errors.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_SUPPORT_ERROR_H
15#define LLVM_SUPPORT_ERROR_H
16
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/ADT/Twine.h"
21#include "llvm/Config/abi-breaking.h"
22#include "llvm/Support/AlignOf.h"
23#include "llvm/Support/Compiler.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Support/ErrorOr.h"
27#include "llvm/Support/raw_ostream.h"
28#include <algorithm>
29#include <cassert>
30#include <cstdint>
31#include <cstdlib>
32#include <functional>
33#include <memory>
34#include <new>
35#include <string>
36#include <system_error>
37#include <type_traits>
38#include <utility>
39#include <vector>
40
41namespace llvm {
42
43class ErrorSuccess;
44
45/// Base class for error info classes. Do not extend this directly: Extend
46/// the ErrorInfo template subclass instead.
47class ErrorInfoBase {
48public:
49 virtual ~ErrorInfoBase() = default;
50
51 /// Print an error message to an output stream.
52 virtual void log(raw_ostream &OS) const = 0;
53
54 /// Return the error message as a string.
55 virtual std::string message() const {
56 std::string Msg;
57 raw_string_ostream OS(Msg);
58 log(OS);
59 return OS.str();
60 }
61
62 /// Convert this error to a std::error_code.
63 ///
64 /// This is a temporary crutch to enable interaction with code still
65 /// using std::error_code. It will be removed in the future.
66 virtual std::error_code convertToErrorCode() const = 0;
67
68 // Returns the class ID for this type.
69 static const void *classID() { return &ID; }
70
71 // Returns the class ID for the dynamic type of this ErrorInfoBase instance.
72 virtual const void *dynamicClassID() const = 0;
73
74 // Check whether this instance is a subclass of the class identified by
75 // ClassID.
76 virtual bool isA(const void *const ClassID) const {
77 return ClassID == classID();
78 }
79
80 // Check whether this instance is a subclass of ErrorInfoT.
81 template <typename ErrorInfoT> bool isA() const {
82 return isA(ErrorInfoT::classID());
83 }
84
85private:
86 virtual void anchor();
87
88 static char ID;
89};
90
91/// Lightweight error class with error context and mandatory checking.
92///
93/// Instances of this class wrap a ErrorInfoBase pointer. Failure states
94/// are represented by setting the pointer to a ErrorInfoBase subclass
95/// instance containing information describing the failure. Success is
96/// represented by a null pointer value.
97///
98/// Instances of Error also contains a 'Checked' flag, which must be set
99/// before the destructor is called, otherwise the destructor will trigger a
100/// runtime error. This enforces at runtime the requirement that all Error
101/// instances be checked or returned to the caller.
102///
103/// There are two ways to set the checked flag, depending on what state the
104/// Error instance is in. For Error instances indicating success, it
105/// is sufficient to invoke the boolean conversion operator. E.g.:
106///
107/// @code{.cpp}
108/// Error foo(<...>);
109///
110/// if (auto E = foo(<...>))
111/// return E; // <- Return E if it is in the error state.
112/// // We have verified that E was in the success state. It can now be safely
113/// // destroyed.
114/// @endcode
115///
116/// A success value *can not* be dropped. For example, just calling 'foo(<...>)'
117/// without testing the return value will raise a runtime error, even if foo
118/// returns success.
119///
120/// For Error instances representing failure, you must use either the
121/// handleErrors or handleAllErrors function with a typed handler. E.g.:
122///
123/// @code{.cpp}
124/// class MyErrorInfo : public ErrorInfo<MyErrorInfo> {
125/// // Custom error info.
126/// };
127///
128/// Error foo(<...>) { return make_error<MyErrorInfo>(...); }
129///
130/// auto E = foo(<...>); // <- foo returns failure with MyErrorInfo.
131/// auto NewE =
132/// handleErrors(E,
133/// [](const MyErrorInfo &M) {
134/// // Deal with the error.
135/// },
136/// [](std::unique_ptr<OtherError> M) -> Error {
137/// if (canHandle(*M)) {
138/// // handle error.
139/// return Error::success();
140/// }
141/// // Couldn't handle this error instance. Pass it up the stack.
142/// return Error(std::move(M));
143/// );
144/// // Note - we must check or return NewE in case any of the handlers
145/// // returned a new error.
146/// @endcode
147///
148/// The handleAllErrors function is identical to handleErrors, except
149/// that it has a void return type, and requires all errors to be handled and
150/// no new errors be returned. It prevents errors (assuming they can all be
151/// handled) from having to be bubbled all the way to the top-level.
152///
153/// *All* Error instances must be checked before destruction, even if
154/// they're moved-assigned or constructed from Success values that have already
155/// been checked. This enforces checking through all levels of the call stack.
156class LLVM_NODISCARD[[clang::warn_unused_result]] Error {
157 // ErrorList needs to be able to yank ErrorInfoBase pointers out of this
158 // class to add to the error list.
159 friend class ErrorList;
160
161 // handleErrors needs to be able to set the Checked flag.
162 template <typename... HandlerTs>
163 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
164
165 // Expected<T> needs to be able to steal the payload when constructed from an
166 // error.
167 template <typename T> friend class Expected;
168
169protected:
170 /// Create a success value. Prefer using 'Error::success()' for readability
171 Error() {
172 setPtr(nullptr);
173 setChecked(false);
174 }
175
176public:
177 /// Create a success value.
178 static ErrorSuccess success();
179
180 // Errors are not copy-constructable.
181 Error(const Error &Other) = delete;
182
183 /// Move-construct an error value. The newly constructed error is considered
184 /// unchecked, even if the source error had been checked. The original error
185 /// becomes a checked Success value, regardless of its original state.
186 Error(Error &&Other) {
187 setChecked(true);
23
Calling 'Error::setChecked'
25
Returning from 'Error::setChecked'
188 *this = std::move(Other);
26
Calling 'move'
27
Returning from 'move'
28
Calling move assignment operator for 'Error'
45
Returning from move assignment operator for 'Error'
189 }
190
191 /// Create an error value. Prefer using the 'make_error' function, but
192 /// this constructor can be useful when "re-throwing" errors from handlers.
193 Error(std::unique_ptr<ErrorInfoBase> Payload) {
194 setPtr(Payload.release());
195 setChecked(false);
196 }
197
198 // Errors are not copy-assignable.
199 Error &operator=(const Error &Other) = delete;
200
201 /// Move-assign an error value. The current error must represent success, you
202 /// you cannot overwrite an unhandled error. The current error is then
203 /// considered unchecked. The source error becomes a checked success value,
204 /// regardless of its original state.
205 Error &operator=(Error &&Other) {
206 // Don't allow overwriting of unchecked values.
207 assertIsChecked();
29
Calling 'Error::assertIsChecked'
32
Returning from 'Error::assertIsChecked'
208 setPtr(Other.getPtr());
33
Calling 'Error::getPtr'
34
Returning from 'Error::getPtr'
35
Calling 'Error::setPtr'
36
Returning from 'Error::setPtr'
209
210 // This Error is unchecked, even if the source error was checked.
211 setChecked(false);
37
Calling 'Error::setChecked'
39
Returning from 'Error::setChecked'
212
213 // Null out Other's payload and set its checked bit.
214 Other.setPtr(nullptr);
40
Calling 'Error::setPtr'
41
Returning from 'Error::setPtr'
215 Other.setChecked(true);
42
Calling 'Error::setChecked'
44
Returning from 'Error::setChecked'
216
217 return *this;
218 }
219
220 /// Destroy a Error. Fails with a call to abort() if the error is
221 /// unchecked.
222 ~Error() {
223 assertIsChecked();
59
Calling 'Error::assertIsChecked'
62
Returning from 'Error::assertIsChecked'
224 delete getPtr();
63
Calling 'Error::getPtr'
64
Returning from 'Error::getPtr'
225 }
226
227 /// Bool conversion. Returns true if this Error is in a failure state,
228 /// and false if it is in an accept state. If the error is in a Success state
229 /// it will be considered checked.
230 explicit operator bool() {
231 setChecked(getPtr() == nullptr);
48
Calling 'Error::getPtr'
49
Returning from 'Error::getPtr'
50
Calling 'Error::setChecked'
53
Returning from 'Error::setChecked'
232 return getPtr() != nullptr;
54
Calling 'Error::getPtr'
55
Returning from 'Error::getPtr'
233 }
234
235 /// Check whether one error is a subclass of another.
236 template <typename ErrT> bool isA() const {
237 return getPtr() && getPtr()->isA(ErrT::classID());
238 }
239
240 /// Returns the dynamic class id of this error, or null if this is a success
241 /// value.
242 const void* dynamicClassID() const {
243 if (!getPtr())
244 return nullptr;
245 return getPtr()->dynamicClassID();
246 }
247
248private:
249#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
250 // assertIsChecked() happens very frequently, but under normal circumstances
251 // is supposed to be a no-op. So we want it to be inlined, but having a bunch
252 // of debug prints can cause the function to be too large for inlining. So
253 // it's important that we define this function out of line so that it can't be
254 // inlined.
255 LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
256 void fatalUncheckedError() const;
257#endif
258
259 void assertIsChecked() {
260#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
261 if (LLVM_UNLIKELY(!getChecked() || getPtr())__builtin_expect((bool)(!getChecked() || getPtr()), false))
30
Within the expansion of the macro 'LLVM_UNLIKELY':
a
Calling 'Error::getChecked'
b
Returning from 'Error::getChecked'
c
Calling 'Error::getPtr'
d
Returning from 'Error::getPtr'
31
Taking false branch
60
Within the expansion of the macro 'LLVM_UNLIKELY':
a
Calling 'Error::getChecked'
b
Returning from 'Error::getChecked'
61
Taking false branch
262 fatalUncheckedError();
263#endif
264 }
265
266 ErrorInfoBase *getPtr() const {
267 return reinterpret_cast<ErrorInfoBase*>(
268 reinterpret_cast<uintptr_t>(Payload) &
269 ~static_cast<uintptr_t>(0x1));
270 }
271
272 void setPtr(ErrorInfoBase *EI) {
273#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
274 Payload = reinterpret_cast<ErrorInfoBase*>(
275 (reinterpret_cast<uintptr_t>(EI) &
276 ~static_cast<uintptr_t>(0x1)) |
277 (reinterpret_cast<uintptr_t>(Payload) & 0x1));
278#else
279 Payload = EI;
280#endif
281 }
282
283 bool getChecked() const {
284#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
285 return (reinterpret_cast<uintptr_t>(Payload) & 0x1) == 0;
286#else
287 return true;
288#endif
289 }
290
291 void setChecked(bool V) {
292 Payload = reinterpret_cast<ErrorInfoBase*>(
293 (reinterpret_cast<uintptr_t>(Payload) &
294 ~static_cast<uintptr_t>(0x1)) |
295 (V ? 0 : 1));
24
'?' condition is true
38
'?' condition is false
43
'?' condition is true
51
Assuming 'V' is 0
52
'?' condition is false
296 }
297
298 std::unique_ptr<ErrorInfoBase> takePayload() {
299 std::unique_ptr<ErrorInfoBase> Tmp(getPtr());
300 setPtr(nullptr);
301 setChecked(true);
302 return Tmp;
303 }
304
305 ErrorInfoBase *Payload = nullptr;
306};
307
308/// Subclass of Error for the sole purpose of identifying the success path in
309/// the type system. This allows to catch invalid conversion to Expected<T> at
310/// compile time.
311class ErrorSuccess : public Error {};
312
313inline ErrorSuccess Error::success() { return ErrorSuccess(); }
314
315/// Make a Error instance representing failure using the given error info
316/// type.
317template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
318 return Error(llvm::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
7
Calling 'forward'
8
Returning from 'forward'
9
Calling 'make_unique'
19
Returning from 'make_unique'
319}
320
321/// Base class for user error types. Users should declare their error types
322/// like:
323///
324/// class MyError : public ErrorInfo<MyError> {
325/// ....
326/// };
327///
328/// This class provides an implementation of the ErrorInfoBase::kind
329/// method, which is used by the Error RTTI system.
330template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
331class ErrorInfo : public ParentErrT {
332public:
333 static const void *classID() { return &ThisErrT::ID; }
334
335 const void *dynamicClassID() const override { return &ThisErrT::ID; }
336
337 bool isA(const void *const ClassID) const override {
338 return ClassID == classID() || ParentErrT::isA(ClassID);
339 }
340};
341
342/// Special ErrorInfo subclass representing a list of ErrorInfos.
343/// Instances of this class are constructed by joinError.
344class ErrorList final : public ErrorInfo<ErrorList> {
345 // handleErrors needs to be able to iterate the payload list of an
346 // ErrorList.
347 template <typename... HandlerTs>
348 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
349
350 // joinErrors is implemented in terms of join.
351 friend Error joinErrors(Error, Error);
352
353public:
354 void log(raw_ostream &OS) const override {
355 OS << "Multiple errors:\n";
356 for (auto &ErrPayload : Payloads) {
357 ErrPayload->log(OS);
358 OS << "\n";
359 }
360 }
361
362 std::error_code convertToErrorCode() const override;
363
364 // Used by ErrorInfo::classID.
365 static char ID;
366
367private:
368 ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
369 std::unique_ptr<ErrorInfoBase> Payload2) {
370 assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() &&(static_cast <bool> (!Payload1->isA<ErrorList>
() && !Payload2->isA<ErrorList>() &&
"ErrorList constructor payloads should be singleton errors")
? void (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 371, __extension__ __PRETTY_FUNCTION__))
371 "ErrorList constructor payloads should be singleton errors")(static_cast <bool> (!Payload1->isA<ErrorList>
() && !Payload2->isA<ErrorList>() &&
"ErrorList constructor payloads should be singleton errors")
? void (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 371, __extension__ __PRETTY_FUNCTION__))
;
372 Payloads.push_back(std::move(Payload1));
373 Payloads.push_back(std::move(Payload2));
374 }
375
376 static Error join(Error E1, Error E2) {
377 if (!E1)
378 return E2;
379 if (!E2)
380 return E1;
381 if (E1.isA<ErrorList>()) {
382 auto &E1List = static_cast<ErrorList &>(*E1.getPtr());
383 if (E2.isA<ErrorList>()) {
384 auto E2Payload = E2.takePayload();
385 auto &E2List = static_cast<ErrorList &>(*E2Payload);
386 for (auto &Payload : E2List.Payloads)
387 E1List.Payloads.push_back(std::move(Payload));
388 } else
389 E1List.Payloads.push_back(E2.takePayload());
390
391 return E1;
392 }
393 if (E2.isA<ErrorList>()) {
394 auto &E2List = static_cast<ErrorList &>(*E2.getPtr());
395 E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload());
396 return E2;
397 }
398 return Error(std::unique_ptr<ErrorList>(
399 new ErrorList(E1.takePayload(), E2.takePayload())));
400 }
401
402 std::vector<std::unique_ptr<ErrorInfoBase>> Payloads;
403};
404
405/// Concatenate errors. The resulting Error is unchecked, and contains the
406/// ErrorInfo(s), if any, contained in E1, followed by the
407/// ErrorInfo(s), if any, contained in E2.
408inline Error joinErrors(Error E1, Error E2) {
409 return ErrorList::join(std::move(E1), std::move(E2));
410}
411
412/// Tagged union holding either a T or a Error.
413///
414/// This class parallels ErrorOr, but replaces error_code with Error. Since
415/// Error cannot be copied, this class replaces getError() with
416/// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the
417/// error class type.
418template <class T> class LLVM_NODISCARD[[clang::warn_unused_result]] Expected {
419 template <class T1> friend class ExpectedAsOutParameter;
420 template <class OtherT> friend class Expected;
421
422 static const bool isRef = std::is_reference<T>::value;
423
424 using wrap = ReferenceStorage<typename std::remove_reference<T>::type>;
425
426 using error_type = std::unique_ptr<ErrorInfoBase>;
427
428public:
429 using storage_type = typename std::conditional<isRef, wrap, T>::type;
430 using value_type = T;
431
432private:
433 using reference = typename std::remove_reference<T>::type &;
434 using const_reference = const typename std::remove_reference<T>::type &;
435 using pointer = typename std::remove_reference<T>::type *;
436 using const_pointer = const typename std::remove_reference<T>::type *;
437
438public:
439 /// Create an Expected<T> error value from the given Error.
440 Expected(Error Err)
441 : HasError(true)
442#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
443 // Expected is unchecked upon construction in Debug builds.
444 , Unchecked(true)
445#endif
446 {
447 assert(Err && "Cannot create Expected<T> from Error success value.")(static_cast <bool> (Err && "Cannot create Expected<T> from Error success value."
) ? void (0) : __assert_fail ("Err && \"Cannot create Expected<T> from Error success value.\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 447, __extension__ __PRETTY_FUNCTION__))
;
448 new (getErrorStorage()) error_type(Err.takePayload());
449 }
450
451 /// Forbid to convert from Error::success() implicitly, this avoids having
452 /// Expected<T> foo() { return Error::success(); } which compiles otherwise
453 /// but triggers the assertion above.
454 Expected(ErrorSuccess) = delete;
455
456 /// Create an Expected<T> success value from the given OtherT value, which
457 /// must be convertible to T.
458 template <typename OtherT>
459 Expected(OtherT &&Val,
460 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
461 * = nullptr)
462 : HasError(false)
463#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
464 // Expected is unchecked upon construction in Debug builds.
465 , Unchecked(true)
466#endif
467 {
468 new (getStorage()) storage_type(std::forward<OtherT>(Val));
469 }
470
471 /// Move construct an Expected<T> value.
472 Expected(Expected &&Other) { moveConstruct(std::move(Other)); }
473
474 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
475 /// must be convertible to T.
476 template <class OtherT>
477 Expected(Expected<OtherT> &&Other,
478 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
479 * = nullptr) {
480 moveConstruct(std::move(Other));
481 }
482
483 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
484 /// isn't convertible to T.
485 template <class OtherT>
486 explicit Expected(
487 Expected<OtherT> &&Other,
488 typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
489 nullptr) {
490 moveConstruct(std::move(Other));
491 }
492
493 /// Move-assign from another Expected<T>.
494 Expected &operator=(Expected &&Other) {
495 moveAssign(std::move(Other));
496 return *this;
497 }
498
499 /// Destroy an Expected<T>.
500 ~Expected() {
501 assertIsChecked();
502 if (!HasError)
503 getStorage()->~storage_type();
504 else
505 getErrorStorage()->~error_type();
506 }
507
508 /// \brief Return false if there is an error.
509 explicit operator bool() {
510#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
511 Unchecked = HasError;
512#endif
513 return !HasError;
514 }
515
516 /// \brief Returns a reference to the stored T value.
517 reference get() {
518 assertIsChecked();
519 return *getStorage();
520 }
521
522 /// \brief Returns a const reference to the stored T value.
523 const_reference get() const {
524 assertIsChecked();
525 return const_cast<Expected<T> *>(this)->get();
526 }
527
528 /// \brief Check that this Expected<T> is an error of type ErrT.
529 template <typename ErrT> bool errorIsA() const {
530 return HasError && (*getErrorStorage())->template isA<ErrT>();
531 }
532
533 /// \brief Take ownership of the stored error.
534 /// After calling this the Expected<T> is in an indeterminate state that can
535 /// only be safely destructed. No further calls (beside the destructor) should
536 /// be made on the Expected<T> vaule.
537 Error takeError() {
538#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
539 Unchecked = false;
540#endif
541 return HasError ? Error(std::move(*getErrorStorage())) : Error::success();
542 }
543
544 /// \brief Returns a pointer to the stored T value.
545 pointer operator->() {
546 assertIsChecked();
547 return toPointer(getStorage());
548 }
549
550 /// \brief Returns a const pointer to the stored T value.
551 const_pointer operator->() const {
552 assertIsChecked();
553 return toPointer(getStorage());
554 }
555
556 /// \brief Returns a reference to the stored T value.
557 reference operator*() {
558 assertIsChecked();
559 return *getStorage();
560 }
561
562 /// \brief Returns a const reference to the stored T value.
563 const_reference operator*() const {
564 assertIsChecked();
565 return *getStorage();
566 }
567
568private:
569 template <class T1>
570 static bool compareThisIfSameType(const T1 &a, const T1 &b) {
571 return &a == &b;
572 }
573
574 template <class T1, class T2>
575 static bool compareThisIfSameType(const T1 &a, const T2 &b) {
576 return false;
577 }
578
579 template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) {
580 HasError = Other.HasError;
581#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
582 Unchecked = true;
583 Other.Unchecked = false;
584#endif
585
586 if (!HasError)
587 new (getStorage()) storage_type(std::move(*Other.getStorage()));
588 else
589 new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
590 }
591
592 template <class OtherT> void moveAssign(Expected<OtherT> &&Other) {
593 assertIsChecked();
594
595 if (compareThisIfSameType(*this, Other))
596 return;
597
598 this->~Expected();
599 new (this) Expected(std::move(Other));
600 }
601
602 pointer toPointer(pointer Val) { return Val; }
603
604 const_pointer toPointer(const_pointer Val) const { return Val; }
605
606 pointer toPointer(wrap *Val) { return &Val->get(); }
607
608 const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
609
610 storage_type *getStorage() {
611 assert(!HasError && "Cannot get value when an error exists!")(static_cast <bool> (!HasError && "Cannot get value when an error exists!"
) ? void (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 611, __extension__ __PRETTY_FUNCTION__))
;
612 return reinterpret_cast<storage_type *>(TStorage.buffer);
613 }
614
615 const storage_type *getStorage() const {
616 assert(!HasError && "Cannot get value when an error exists!")(static_cast <bool> (!HasError && "Cannot get value when an error exists!"
) ? void (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 616, __extension__ __PRETTY_FUNCTION__))
;
617 return reinterpret_cast<const storage_type *>(TStorage.buffer);
618 }
619
620 error_type *getErrorStorage() {
621 assert(HasError && "Cannot get error when a value exists!")(static_cast <bool> (HasError && "Cannot get error when a value exists!"
) ? void (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 621, __extension__ __PRETTY_FUNCTION__))
;
622 return reinterpret_cast<error_type *>(ErrorStorage.buffer);
623 }
624
625 const error_type *getErrorStorage() const {
626 assert(HasError && "Cannot get error when a value exists!")(static_cast <bool> (HasError && "Cannot get error when a value exists!"
) ? void (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 626, __extension__ __PRETTY_FUNCTION__))
;
627 return reinterpret_cast<const error_type *>(ErrorStorage.buffer);
628 }
629
630 // Used by ExpectedAsOutParameter to reset the checked flag.
631 void setUnchecked() {
632#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
633 Unchecked = true;
634#endif
635 }
636
637#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
638 LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
639 LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline))
640 void fatalUncheckedExpected() const {
641 dbgs() << "Expected<T> must be checked before access or destruction.\n";
642 if (HasError) {
643 dbgs() << "Unchecked Expected<T> contained error:\n";
644 (*getErrorStorage())->log(dbgs());
645 } else
646 dbgs() << "Expected<T> value was in success state. (Note: Expected<T> "
647 "values in success mode must still be checked prior to being "
648 "destroyed).\n";
649 abort();
650 }
651#endif
652
653 void assertIsChecked() {
654#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
655 if (LLVM_UNLIKELY(Unchecked)__builtin_expect((bool)(Unchecked), false))
656 fatalUncheckedExpected();
657#endif
658 }
659
660 union {
661 AlignedCharArrayUnion<storage_type> TStorage;
662 AlignedCharArrayUnion<error_type> ErrorStorage;
663 };
664 bool HasError : 1;
665#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
666 bool Unchecked : 1;
667#endif
668};
669
670/// Report a serious error, calling any installed error handler. See
671/// ErrorHandling.h.
672LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) void report_fatal_error(Error Err,
673 bool gen_crash_diag = true);
674
675/// Report a fatal error if Err is a failure value.
676///
677/// This function can be used to wrap calls to fallible functions ONLY when it
678/// is known that the Error will always be a success value. E.g.
679///
680/// @code{.cpp}
681/// // foo only attempts the fallible operation if DoFallibleOperation is
682/// // true. If DoFallibleOperation is false then foo always returns
683/// // Error::success().
684/// Error foo(bool DoFallibleOperation);
685///
686/// cantFail(foo(false));
687/// @endcode
688inline void cantFail(Error Err, const char *Msg = nullptr) {
689 if (Err) {
690 if (!Msg)
691 Msg = "Failure value returned from cantFail wrapped call";
692 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 692)
;
693 }
694}
695
696/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
697/// returns the contained value.
698///
699/// This function can be used to wrap calls to fallible functions ONLY when it
700/// is known that the Error will always be a success value. E.g.
701///
702/// @code{.cpp}
703/// // foo only attempts the fallible operation if DoFallibleOperation is
704/// // true. If DoFallibleOperation is false then foo always returns an int.
705/// Expected<int> foo(bool DoFallibleOperation);
706///
707/// int X = cantFail(foo(false));
708/// @endcode
709template <typename T>
710T cantFail(Expected<T> ValOrErr, const char *Msg = nullptr) {
711 if (ValOrErr)
712 return std::move(*ValOrErr);
713 else {
714 if (!Msg)
715 Msg = "Failure value returned from cantFail wrapped call";
716 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 716)
;
717 }
718}
719
720/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
721/// returns the contained reference.
722///
723/// This function can be used to wrap calls to fallible functions ONLY when it
724/// is known that the Error will always be a success value. E.g.
725///
726/// @code{.cpp}
727/// // foo only attempts the fallible operation if DoFallibleOperation is
728/// // true. If DoFallibleOperation is false then foo always returns a Bar&.
729/// Expected<Bar&> foo(bool DoFallibleOperation);
730///
731/// Bar &X = cantFail(foo(false));
732/// @endcode
733template <typename T>
734T& cantFail(Expected<T&> ValOrErr, const char *Msg = nullptr) {
735 if (ValOrErr)
736 return *ValOrErr;
737 else {
738 if (!Msg)
739 Msg = "Failure value returned from cantFail wrapped call";
740 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 740)
;
741 }
742}
743
744/// Helper for testing applicability of, and applying, handlers for
745/// ErrorInfo types.
746template <typename HandlerT>
747class ErrorHandlerTraits
748 : public ErrorHandlerTraits<decltype(
749 &std::remove_reference<HandlerT>::type::operator())> {};
750
751// Specialization functions of the form 'Error (const ErrT&)'.
752template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
753public:
754 static bool appliesTo(const ErrorInfoBase &E) {
755 return E.template isA<ErrT>();
756 }
757
758 template <typename HandlerT>
759 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
760 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 760, __extension__ __PRETTY_FUNCTION__))
;
761 return H(static_cast<ErrT &>(*E));
762 }
763};
764
765// Specialization functions of the form 'void (const ErrT&)'.
766template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
767public:
768 static bool appliesTo(const ErrorInfoBase &E) {
769 return E.template isA<ErrT>();
770 }
771
772 template <typename HandlerT>
773 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
774 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 774, __extension__ __PRETTY_FUNCTION__))
;
775 H(static_cast<ErrT &>(*E));
776 return Error::success();
777 }
778};
779
780/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
781template <typename ErrT>
782class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
783public:
784 static bool appliesTo(const ErrorInfoBase &E) {
785 return E.template isA<ErrT>();
786 }
787
788 template <typename HandlerT>
789 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
790 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 790, __extension__ __PRETTY_FUNCTION__))
;
791 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
792 return H(std::move(SubE));
793 }
794};
795
796/// Specialization for functions of the form 'void (std::unique_ptr<ErrT>)'.
797template <typename ErrT>
798class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
799public:
800 static bool appliesTo(const ErrorInfoBase &E) {
801 return E.template isA<ErrT>();
802 }
803
804 template <typename HandlerT>
805 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
806 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 806, __extension__ __PRETTY_FUNCTION__))
;
807 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
808 H(std::move(SubE));
809 return Error::success();
810 }
811};
812
813// Specialization for member functions of the form 'RetT (const ErrT&)'.
814template <typename C, typename RetT, typename ErrT>
815class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
816 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
817
818// Specialization for member functions of the form 'RetT (const ErrT&) const'.
819template <typename C, typename RetT, typename ErrT>
820class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
821 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
822
823// Specialization for member functions of the form 'RetT (const ErrT&)'.
824template <typename C, typename RetT, typename ErrT>
825class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
826 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
827
828// Specialization for member functions of the form 'RetT (const ErrT&) const'.
829template <typename C, typename RetT, typename ErrT>
830class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
831 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
832
833/// Specialization for member functions of the form
834/// 'RetT (std::unique_ptr<ErrT>)'.
835template <typename C, typename RetT, typename ErrT>
836class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
837 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
838
839/// Specialization for member functions of the form
840/// 'RetT (std::unique_ptr<ErrT>) const'.
841template <typename C, typename RetT, typename ErrT>
842class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
843 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
844
845inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
846 return Error(std::move(Payload));
847}
848
849template <typename HandlerT, typename... HandlerTs>
850Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
851 HandlerT &&Handler, HandlerTs &&... Handlers) {
852 if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
853 return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
854 std::move(Payload));
855 return handleErrorImpl(std::move(Payload),
856 std::forward<HandlerTs>(Handlers)...);
857}
858
859/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any
860/// unhandled errors (or Errors returned by handlers) are re-concatenated and
861/// returned.
862/// Because this function returns an error, its result must also be checked
863/// or returned. If you intend to handle all errors use handleAllErrors
864/// (which returns void, and will abort() on unhandled errors) instead.
865template <typename... HandlerTs>
866Error handleErrors(Error E, HandlerTs &&... Hs) {
867 if (!E)
868 return Error::success();
869
870 std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
871
872 if (Payload->isA<ErrorList>()) {
873 ErrorList &List = static_cast<ErrorList &>(*Payload);
874 Error R;
875 for (auto &P : List.Payloads)
876 R = ErrorList::join(
877 std::move(R),
878 handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
879 return R;
880 }
881
882 return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...);
883}
884
885/// Behaves the same as handleErrors, except that it requires that all
886/// errors be handled by the given handlers. If any unhandled error remains
887/// after the handlers have run, report_fatal_error() will be called.
888template <typename... HandlerTs>
889void handleAllErrors(Error E, HandlerTs &&... Handlers) {
890 cantFail(handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...));
891}
892
893/// Check that E is a non-error, then drop it.
894/// If E is an error report_fatal_error will be called.
895inline void handleAllErrors(Error E) {
896 cantFail(std::move(E));
897}
898
899/// Handle any errors (if present) in an Expected<T>, then try a recovery path.
900///
901/// If the incoming value is a success value it is returned unmodified. If it
902/// is a failure value then it the contained error is passed to handleErrors.
903/// If handleErrors is able to handle the error then the RecoveryPath functor
904/// is called to supply the final result. If handleErrors is not able to
905/// handle all errors then the unhandled errors are returned.
906///
907/// This utility enables the follow pattern:
908///
909/// @code{.cpp}
910/// enum FooStrategy { Aggressive, Conservative };
911/// Expected<Foo> foo(FooStrategy S);
912///
913/// auto ResultOrErr =
914/// handleExpected(
915/// foo(Aggressive),
916/// []() { return foo(Conservative); },
917/// [](AggressiveStrategyError&) {
918/// // Implicitly conusme this - we'll recover by using a conservative
919/// // strategy.
920/// });
921///
922/// @endcode
923template <typename T, typename RecoveryFtor, typename... HandlerTs>
924Expected<T> handleExpected(Expected<T> ValOrErr, RecoveryFtor &&RecoveryPath,
925 HandlerTs &&... Handlers) {
926 if (ValOrErr)
927 return ValOrErr;
928
929 if (auto Err = handleErrors(ValOrErr.takeError(),
930 std::forward<HandlerTs>(Handlers)...))
931 return std::move(Err);
932
933 return RecoveryPath();
934}
935
936/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner
937/// will be printed before the first one is logged. A newline will be printed
938/// after each error.
939///
940/// This is useful in the base level of your program to allow clean termination
941/// (allowing clean deallocation of resources, etc.), while reporting error
942/// information to the user.
943void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner);
944
945/// Write all error messages (if any) in E to a string. The newline character
946/// is used to separate error messages.
947inline std::string toString(Error E) {
948 SmallVector<std::string, 2> Errors;
949 handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) {
950 Errors.push_back(EI.message());
951 });
952 return join(Errors.begin(), Errors.end(), "\n");
953}
954
955/// Consume a Error without doing anything. This method should be used
956/// only where an error can be considered a reasonable and expected return
957/// value.
958///
959/// Uses of this method are potentially indicative of design problems: If it's
960/// legitimate to do nothing while processing an "error", the error-producer
961/// might be more clearly refactored to return an Optional<T>.
962inline void consumeError(Error Err) {
963 handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
964}
965
966/// Helper for converting an Error to a bool.
967///
968/// This method returns true if Err is in an error state, or false if it is
969/// in a success state. Puts Err in a checked state in both cases (unlike
970/// Error::operator bool(), which only does this for success states).
971inline bool errorToBool(Error Err) {
972 bool IsError = static_cast<bool>(Err);
973 if (IsError)
974 consumeError(std::move(Err));
975 return IsError;
976}
977
978/// Helper for Errors used as out-parameters.
979///
980/// This helper is for use with the Error-as-out-parameter idiom, where an error
981/// is passed to a function or method by reference, rather than being returned.
982/// In such cases it is helpful to set the checked bit on entry to the function
983/// so that the error can be written to (unchecked Errors abort on assignment)
984/// and clear the checked bit on exit so that clients cannot accidentally forget
985/// to check the result. This helper performs these actions automatically using
986/// RAII:
987///
988/// @code{.cpp}
989/// Result foo(Error &Err) {
990/// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
991/// // <body of foo>
992/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
993/// }
994/// @endcode
995///
996/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
997/// used with optional Errors (Error pointers that are allowed to be null). If
998/// ErrorAsOutParameter took an Error reference, an instance would have to be
999/// created inside every condition that verified that Error was non-null. By
1000/// taking an Error pointer we can just create one instance at the top of the
1001/// function.
1002class ErrorAsOutParameter {
1003public:
1004 ErrorAsOutParameter(Error *Err) : Err(Err) {
1005 // Raise the checked bit if Err is success.
1006 if (Err)
1007 (void)!!*Err;
1008 }
1009
1010 ~ErrorAsOutParameter() {
1011 // Clear the checked bit.
1012 if (Err && !*Err)
1013 *Err = Error::success();
1014 }
1015
1016private:
1017 Error *Err;
1018};
1019
1020/// Helper for Expected<T>s used as out-parameters.
1021///
1022/// See ErrorAsOutParameter.
1023template <typename T>
1024class ExpectedAsOutParameter {
1025public:
1026 ExpectedAsOutParameter(Expected<T> *ValOrErr)
1027 : ValOrErr(ValOrErr) {
1028 if (ValOrErr)
1029 (void)!!*ValOrErr;
1030 }
1031
1032 ~ExpectedAsOutParameter() {
1033 if (ValOrErr)
1034 ValOrErr->setUnchecked();
1035 }
1036
1037private:
1038 Expected<T> *ValOrErr;
1039};
1040
1041/// This class wraps a std::error_code in a Error.
1042///
1043/// This is useful if you're writing an interface that returns a Error
1044/// (or Expected) and you want to call code that still returns
1045/// std::error_codes.
1046class ECError : public ErrorInfo<ECError> {
1047 friend Error errorCodeToError(std::error_code);
1048
1049public:
1050 void setErrorCode(std::error_code EC) { this->EC = EC; }
1051 std::error_code convertToErrorCode() const override { return EC; }
1052 void log(raw_ostream &OS) const override { OS << EC.message(); }
1053
1054 // Used by ErrorInfo::classID.
1055 static char ID;
1056
1057protected:
1058 ECError() = default;
1059 ECError(std::error_code EC) : EC(EC) {}
1060
1061 std::error_code EC;
1062};
1063
1064/// The value returned by this function can be returned from convertToErrorCode
1065/// for Error values where no sensible translation to std::error_code exists.
1066/// It should only be used in this situation, and should never be used where a
1067/// sensible conversion to std::error_code is available, as attempts to convert
1068/// to/from this error will result in a fatal error. (i.e. it is a programmatic
1069///error to try to convert such a value).
1070std::error_code inconvertibleErrorCode();
1071
1072/// Helper for converting an std::error_code to a Error.
1073Error errorCodeToError(std::error_code EC);
1074
1075/// Helper for converting an ECError to a std::error_code.
1076///
1077/// This method requires that Err be Error() or an ECError, otherwise it
1078/// will trigger a call to abort().
1079std::error_code errorToErrorCode(Error Err);
1080
1081/// Convert an ErrorOr<T> to an Expected<T>.
1082template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
1083 if (auto EC = EO.getError())
1084 return errorCodeToError(EC);
1085 return std::move(*EO);
1086}
1087
1088/// Convert an Expected<T> to an ErrorOr<T>.
1089template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
1090 if (auto Err = E.takeError())
1091 return errorToErrorCode(std::move(Err));
1092 return std::move(*E);
1093}
1094
1095/// This class wraps a string in an Error.
1096///
1097/// StringError is useful in cases where the client is not expected to be able
1098/// to consume the specific error message programmatically (for example, if the
1099/// error message is to be presented to the user).
1100class StringError : public ErrorInfo<StringError> {
1101public:
1102 static char ID;
1103
1104 StringError(const Twine &S, std::error_code EC);
1105
1106 void log(raw_ostream &OS) const override;
1107 std::error_code convertToErrorCode() const override;
1108
1109 const std::string &getMessage() const { return Msg; }
1110
1111private:
1112 std::string Msg;
1113 std::error_code EC;
1114};
1115
1116/// Helper for check-and-exit error handling.
1117///
1118/// For tool use only. NOT FOR USE IN LIBRARY CODE.
1119///
1120class ExitOnError {
1121public:
1122 /// Create an error on exit helper.
1123 ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
1124 : Banner(std::move(Banner)),
1125 GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
1126
1127 /// Set the banner string for any errors caught by operator().
1128 void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
1129
1130 /// Set the exit-code mapper function.
1131 void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
1132 this->GetExitCode = std::move(GetExitCode);
1133 }
1134
1135 /// Check Err. If it's in a failure state log the error(s) and exit.
1136 void operator()(Error Err) const { checkError(std::move(Err)); }
1137
1138 /// Check E. If it's in a success state then return the contained value. If
1139 /// it's in a failure state log the error(s) and exit.
1140 template <typename T> T operator()(Expected<T> &&E) const {
1141 checkError(E.takeError());
1142 return std::move(*E);
1143 }
1144
1145 /// Check E. If it's in a success state then return the contained reference. If
1146 /// it's in a failure state log the error(s) and exit.
1147 template <typename T> T& operator()(Expected<T&> &&E) const {
1148 checkError(E.takeError());
1149 return *E;
1150 }
1151
1152private:
1153 void checkError(Error Err) const {
1154 if (Err) {
1155 int ExitCode = GetExitCode(Err);
1156 logAllUnhandledErrors(std::move(Err), errs(), Banner);
1157 exit(ExitCode);
1158 }
1159 }
1160
1161 std::string Banner;
1162 std::function<int(const Error &)> GetExitCode;
1163};
1164
1165} // end namespace llvm
1166
1167#endif // LLVM_SUPPORT_ERROR_H

/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ADT/STLExtras.h

1//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains some templates that are useful if you are working with the
11// STL at all.
12//
13// No library is required when using these functions.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_ADT_STLEXTRAS_H
18#define LLVM_ADT_STLEXTRAS_H
19
20#include "llvm/ADT/Optional.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/iterator.h"
23#include "llvm/ADT/iterator_range.h"
24#include "llvm/Support/ErrorHandling.h"
25#include <algorithm>
26#include <cassert>
27#include <cstddef>
28#include <cstdint>
29#include <cstdlib>
30#include <functional>
31#include <initializer_list>
32#include <iterator>
33#include <limits>
34#include <memory>
35#include <tuple>
36#include <type_traits>
37#include <utility>
38
39namespace llvm {
40
41// Only used by compiler if both template types are the same. Useful when
42// using SFINAE to test for the existence of member functions.
43template <typename T, T> struct SameType;
44
45namespace detail {
46
47template <typename RangeT>
48using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
49
50template <typename RangeT>
51using ValueOfRange = typename std::remove_reference<decltype(
52 *std::begin(std::declval<RangeT &>()))>::type;
53
54} // end namespace detail
55
56//===----------------------------------------------------------------------===//
57// Extra additions to <functional>
58//===----------------------------------------------------------------------===//
59
60template <class Ty> struct identity {
61 using argument_type = Ty;
62
63 Ty &operator()(Ty &self) const {
64 return self;
65 }
66 const Ty &operator()(const Ty &self) const {
67 return self;
68 }
69};
70
71template <class Ty> struct less_ptr {
72 bool operator()(const Ty* left, const Ty* right) const {
73 return *left < *right;
74 }
75};
76
77template <class Ty> struct greater_ptr {
78 bool operator()(const Ty* left, const Ty* right) const {
79 return *right < *left;
80 }
81};
82
83/// An efficient, type-erasing, non-owning reference to a callable. This is
84/// intended for use as the type of a function parameter that is not used
85/// after the function in question returns.
86///
87/// This class does not own the callable, so it is not in general safe to store
88/// a function_ref.
89template<typename Fn> class function_ref;
90
91template<typename Ret, typename ...Params>
92class function_ref<Ret(Params...)> {
93 Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
94 intptr_t callable;
95
96 template<typename Callable>
97 static Ret callback_fn(intptr_t callable, Params ...params) {
98 return (*reinterpret_cast<Callable*>(callable))(
99 std::forward<Params>(params)...);
100 }
101
102public:
103 function_ref() = default;
104 function_ref(std::nullptr_t) {}
105
106 template <typename Callable>
107 function_ref(Callable &&callable,
108 typename std::enable_if<
109 !std::is_same<typename std::remove_reference<Callable>::type,
110 function_ref>::value>::type * = nullptr)
111 : callback(callback_fn<typename std::remove_reference<Callable>::type>),
112 callable(reinterpret_cast<intptr_t>(&callable)) {}
113
114 Ret operator()(Params ...params) const {
115 return callback(callable, std::forward<Params>(params)...);
116 }
117
118 operator bool() const { return callback; }
119};
120
121// deleter - Very very very simple method that is used to invoke operator
122// delete on something. It is used like this:
123//
124// for_each(V.begin(), B.end(), deleter<Interval>);
125template <class T>
126inline void deleter(T *Ptr) {
127 delete Ptr;
128}
129
130//===----------------------------------------------------------------------===//
131// Extra additions to <iterator>
132//===----------------------------------------------------------------------===//
133
134namespace adl_detail {
135
136using std::begin;
137
138template <typename ContainerTy>
139auto adl_begin(ContainerTy &&container)
140 -> decltype(begin(std::forward<ContainerTy>(container))) {
141 return begin(std::forward<ContainerTy>(container));
142}
143
144using std::end;
145
146template <typename ContainerTy>
147auto adl_end(ContainerTy &&container)
148 -> decltype(end(std::forward<ContainerTy>(container))) {
149 return end(std::forward<ContainerTy>(container));
150}
151
152using std::swap;
153
154template <typename T>
155void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(),
156 std::declval<T>()))) {
157 swap(std::forward<T>(lhs), std::forward<T>(rhs));
158}
159
160} // end namespace adl_detail
161
162template <typename ContainerTy>
163auto adl_begin(ContainerTy &&container)
164 -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) {
165 return adl_detail::adl_begin(std::forward<ContainerTy>(container));
166}
167
168template <typename ContainerTy>
169auto adl_end(ContainerTy &&container)
170 -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) {
171 return adl_detail::adl_end(std::forward<ContainerTy>(container));
172}
173
174template <typename T>
175void adl_swap(T &&lhs, T &&rhs) noexcept(
176 noexcept(adl_detail::adl_swap(std::declval<T>(), std::declval<T>()))) {
177 adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
178}
179
180// mapped_iterator - This is a simple iterator adapter that causes a function to
181// be applied whenever operator* is invoked on the iterator.
182
183template <typename ItTy, typename FuncTy,
184 typename FuncReturnTy =
185 decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
186class mapped_iterator
187 : public iterator_adaptor_base<
188 mapped_iterator<ItTy, FuncTy>, ItTy,
189 typename std::iterator_traits<ItTy>::iterator_category,
190 typename std::remove_reference<FuncReturnTy>::type> {
191public:
192 mapped_iterator(ItTy U, FuncTy F)
193 : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
194
195 ItTy getCurrent() { return this->I; }
196
197 FuncReturnTy operator*() { return F(*this->I); }
198
199private:
200 FuncTy F;
201};
202
203// map_iterator - Provide a convenient way to create mapped_iterators, just like
204// make_pair is useful for creating pairs...
205template <class ItTy, class FuncTy>
206inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) {
207 return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
208}
209
210/// Helper to determine if type T has a member called rbegin().
211template <typename Ty> class has_rbegin_impl {
212 using yes = char[1];
213 using no = char[2];
214
215 template <typename Inner>
216 static yes& test(Inner *I, decltype(I->rbegin()) * = nullptr);
217
218 template <typename>
219 static no& test(...);
220
221public:
222 static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
223};
224
225/// Metafunction to determine if T& or T has a member called rbegin().
226template <typename Ty>
227struct has_rbegin : has_rbegin_impl<typename std::remove_reference<Ty>::type> {
228};
229
230// Returns an iterator_range over the given container which iterates in reverse.
231// Note that the container must have rbegin()/rend() methods for this to work.
232template <typename ContainerTy>
233auto reverse(ContainerTy &&C,
234 typename std::enable_if<has_rbegin<ContainerTy>::value>::type * =
235 nullptr) -> decltype(make_range(C.rbegin(), C.rend())) {
236 return make_range(C.rbegin(), C.rend());
237}
238
239// Returns a std::reverse_iterator wrapped around the given iterator.
240template <typename IteratorTy>
241std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
242 return std::reverse_iterator<IteratorTy>(It);
243}
244
245// Returns an iterator_range over the given container which iterates in reverse.
246// Note that the container must have begin()/end() methods which return
247// bidirectional iterators for this to work.
248template <typename ContainerTy>
249auto reverse(
250 ContainerTy &&C,
251 typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * = nullptr)
252 -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
253 llvm::make_reverse_iterator(std::begin(C)))) {
254 return make_range(llvm::make_reverse_iterator(std::end(C)),
255 llvm::make_reverse_iterator(std::begin(C)));
256}
257
258/// An iterator adaptor that filters the elements of given inner iterators.
259///
260/// The predicate parameter should be a callable object that accepts the wrapped
261/// iterator's reference type and returns a bool. When incrementing or
262/// decrementing the iterator, it will call the predicate on each element and
263/// skip any where it returns false.
264///
265/// \code
266/// int A[] = { 1, 2, 3, 4 };
267/// auto R = make_filter_range(A, [](int N) { return N % 2 == 1; });
268/// // R contains { 1, 3 }.
269/// \endcode
270template <typename WrappedIteratorT, typename PredicateT>
271class filter_iterator
272 : public iterator_adaptor_base<
273 filter_iterator<WrappedIteratorT, PredicateT>, WrappedIteratorT,
274 typename std::common_type<
275 std::forward_iterator_tag,
276 typename std::iterator_traits<
277 WrappedIteratorT>::iterator_category>::type> {
278 using BaseT = iterator_adaptor_base<
279 filter_iterator<WrappedIteratorT, PredicateT>, WrappedIteratorT,
280 typename std::common_type<
281 std::forward_iterator_tag,
282 typename std::iterator_traits<WrappedIteratorT>::iterator_category>::
283 type>;
284
285 struct PayloadType {
286 WrappedIteratorT End;
287 PredicateT Pred;
288 };
289
290 Optional<PayloadType> Payload;
291
292 void findNextValid() {
293 assert(Payload && "Payload should be engaged when findNextValid is called")(static_cast <bool> (Payload && "Payload should be engaged when findNextValid is called"
) ? void (0) : __assert_fail ("Payload && \"Payload should be engaged when findNextValid is called\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ADT/STLExtras.h"
, 293, __extension__ __PRETTY_FUNCTION__))
;
294 while (this->I != Payload->End && !Payload->Pred(*this->I))
295 BaseT::operator++();
296 }
297
298 // Construct the begin iterator. The begin iterator requires to know where end
299 // is, so that it can properly stop when it hits end.
300 filter_iterator(WrappedIteratorT Begin, WrappedIteratorT End, PredicateT Pred)
301 : BaseT(std::move(Begin)),
302 Payload(PayloadType{std::move(End), std::move(Pred)}) {
303 findNextValid();
304 }
305
306 // Construct the end iterator. It's not incrementable, so Payload doesn't
307 // have to be engaged.
308 filter_iterator(WrappedIteratorT End) : BaseT(End) {}
309
310public:
311 using BaseT::operator++;
312
313 filter_iterator &operator++() {
314 BaseT::operator++();
315 findNextValid();
316 return *this;
317 }
318
319 template <typename RT, typename PT>
320 friend iterator_range<filter_iterator<detail::IterOfRange<RT>, PT>>
321 make_filter_range(RT &&, PT);
322};
323
324/// Convenience function that takes a range of elements and a predicate,
325/// and return a new filter_iterator range.
326///
327/// FIXME: Currently if RangeT && is a rvalue reference to a temporary, the
328/// lifetime of that temporary is not kept by the returned range object, and the
329/// temporary is going to be dropped on the floor after the make_iterator_range
330/// full expression that contains this function call.
331template <typename RangeT, typename PredicateT>
332iterator_range<filter_iterator<detail::IterOfRange<RangeT>, PredicateT>>
333make_filter_range(RangeT &&Range, PredicateT Pred) {
334 using FilterIteratorT =
335 filter_iterator<detail::IterOfRange<RangeT>, PredicateT>;
336 return make_range(FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
337 std::end(std::forward<RangeT>(Range)),
338 std::move(Pred)),
339 FilterIteratorT(std::end(std::forward<RangeT>(Range))));
340}
341
342// forward declarations required by zip_shortest/zip_first
343template <typename R, typename UnaryPredicate>
344bool all_of(R &&range, UnaryPredicate P);
345
346template <size_t... I> struct index_sequence;
347
348template <class... Ts> struct index_sequence_for;
349
350namespace detail {
351
352using std::declval;
353
354// We have to alias this since inlining the actual type at the usage site
355// in the parameter list of iterator_facade_base<> below ICEs MSVC 2017.
356template<typename... Iters> struct ZipTupleType {
357 using type = std::tuple<decltype(*declval<Iters>())...>;
358};
359
360template <typename ZipType, typename... Iters>
361using zip_traits = iterator_facade_base<
362 ZipType, typename std::common_type<std::bidirectional_iterator_tag,
363 typename std::iterator_traits<
364 Iters>::iterator_category...>::type,
365 // ^ TODO: Implement random access methods.
366 typename ZipTupleType<Iters...>::type,
367 typename std::iterator_traits<typename std::tuple_element<
368 0, std::tuple<Iters...>>::type>::difference_type,
369 // ^ FIXME: This follows boost::make_zip_iterator's assumption that all
370 // inner iterators have the same difference_type. It would fail if, for
371 // instance, the second field's difference_type were non-numeric while the
372 // first is.
373 typename ZipTupleType<Iters...>::type *,
374 typename ZipTupleType<Iters...>::type>;
375
376template <typename ZipType, typename... Iters>
377struct zip_common : public zip_traits<ZipType, Iters...> {
378 using Base = zip_traits<ZipType, Iters...>;
379 using value_type = typename Base::value_type;
380
381 std::tuple<Iters...> iterators;
382
383protected:
384 template <size_t... Ns> value_type deref(index_sequence<Ns...>) const {
385 return value_type(*std::get<Ns>(iterators)...);
386 }
387
388 template <size_t... Ns>
389 decltype(iterators) tup_inc(index_sequence<Ns...>) const {
390 return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
391 }
392
393 template <size_t... Ns>
394 decltype(iterators) tup_dec(index_sequence<Ns...>) const {
395 return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
396 }
397
398public:
399 zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
400
401 value_type operator*() { return deref(index_sequence_for<Iters...>{}); }
402
403 const value_type operator*() const {
404 return deref(index_sequence_for<Iters...>{});
405 }
406
407 ZipType &operator++() {
408 iterators = tup_inc(index_sequence_for<Iters...>{});
409 return *reinterpret_cast<ZipType *>(this);
410 }
411
412 ZipType &operator--() {
413 static_assert(Base::IsBidirectional,
414 "All inner iterators must be at least bidirectional.");
415 iterators = tup_dec(index_sequence_for<Iters...>{});
416 return *reinterpret_cast<ZipType *>(this);
417 }
418};
419
420template <typename... Iters>
421struct zip_first : public zip_common<zip_first<Iters...>, Iters...> {
422 using Base = zip_common<zip_first<Iters...>, Iters...>;
423
424 bool operator==(const zip_first<Iters...> &other) const {
425 return std::get<0>(this->iterators) == std::get<0>(other.iterators);
426 }
427
428 zip_first(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
429};
430
431template <typename... Iters>
432class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> {
433 template <size_t... Ns>
434 bool test(const zip_shortest<Iters...> &other, index_sequence<Ns...>) const {
435 return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
436 std::get<Ns>(other.iterators)...},
437 identity<bool>{});
438 }
439
440public:
441 using Base = zip_common<zip_shortest<Iters...>, Iters...>;
442
443 zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
444
445 bool operator==(const zip_shortest<Iters...> &other) const {
446 return !test(other, index_sequence_for<Iters...>{});
447 }
448};
449
450template <template <typename...> class ItType, typename... Args> class zippy {
451public:
452 using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
453 using iterator_category = typename iterator::iterator_category;
454 using value_type = typename iterator::value_type;
455 using difference_type = typename iterator::difference_type;
456 using pointer = typename iterator::pointer;
457 using reference = typename iterator::reference;
458
459private:
460 std::tuple<Args...> ts;
461
462 template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const {
463 return iterator(std::begin(std::get<Ns>(ts))...);
464 }
465 template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const {
466 return iterator(std::end(std::get<Ns>(ts))...);
467 }
468
469public:
470 zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
471
472 iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); }
473 iterator end() const { return end_impl(index_sequence_for<Args...>{}); }
474};
475
476} // end namespace detail
477
478/// zip iterator for two or more iteratable types.
479template <typename T, typename U, typename... Args>
480detail::zippy<detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u,
481 Args &&... args) {
482 return detail::zippy<detail::zip_shortest, T, U, Args...>(
483 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
484}
485
486/// zip iterator that, for the sake of efficiency, assumes the first iteratee to
487/// be the shortest.
488template <typename T, typename U, typename... Args>
489detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
490 Args &&... args) {
491 return detail::zippy<detail::zip_first, T, U, Args...>(
492 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
493}
494
495/// Iterator wrapper that concatenates sequences together.
496///
497/// This can concatenate different iterators, even with different types, into
498/// a single iterator provided the value types of all the concatenated
499/// iterators expose `reference` and `pointer` types that can be converted to
500/// `ValueT &` and `ValueT *` respectively. It doesn't support more
501/// interesting/customized pointer or reference types.
502///
503/// Currently this only supports forward or higher iterator categories as
504/// inputs and always exposes a forward iterator interface.
505template <typename ValueT, typename... IterTs>
506class concat_iterator
507 : public iterator_facade_base<concat_iterator<ValueT, IterTs...>,
508 std::forward_iterator_tag, ValueT> {
509 using BaseT = typename concat_iterator::iterator_facade_base;
510
511 /// We store both the current and end iterators for each concatenated
512 /// sequence in a tuple of pairs.
513 ///
514 /// Note that something like iterator_range seems nice at first here, but the
515 /// range properties are of little benefit and end up getting in the way
516 /// because we need to do mutation on the current iterators.
517 std::tuple<std::pair<IterTs, IterTs>...> IterPairs;
518
519 /// Attempts to increment a specific iterator.
520 ///
521 /// Returns true if it was able to increment the iterator. Returns false if
522 /// the iterator is already at the end iterator.
523 template <size_t Index> bool incrementHelper() {
524 auto &IterPair = std::get<Index>(IterPairs);
525 if (IterPair.first == IterPair.second)
526 return false;
527
528 ++IterPair.first;
529 return true;
530 }
531
532 /// Increments the first non-end iterator.
533 ///
534 /// It is an error to call this with all iterators at the end.
535 template <size_t... Ns> void increment(index_sequence<Ns...>) {
536 // Build a sequence of functions to increment each iterator if possible.
537 bool (concat_iterator::*IncrementHelperFns[])() = {
538 &concat_iterator::incrementHelper<Ns>...};
539
540 // Loop over them, and stop as soon as we succeed at incrementing one.
541 for (auto &IncrementHelperFn : IncrementHelperFns)
542 if ((this->*IncrementHelperFn)())
543 return;
544
545 llvm_unreachable("Attempted to increment an end concat iterator!")::llvm::llvm_unreachable_internal("Attempted to increment an end concat iterator!"
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ADT/STLExtras.h"
, 545)
;
546 }
547
548 /// Returns null if the specified iterator is at the end. Otherwise,
549 /// dereferences the iterator and returns the address of the resulting
550 /// reference.
551 template <size_t Index> ValueT *getHelper() const {
552 auto &IterPair = std::get<Index>(IterPairs);
553 if (IterPair.first == IterPair.second)
554 return nullptr;
555
556 return &*IterPair.first;
557 }
558
559 /// Finds the first non-end iterator, dereferences, and returns the resulting
560 /// reference.
561 ///
562 /// It is an error to call this with all iterators at the end.
563 template <size_t... Ns> ValueT &get(index_sequence<Ns...>) const {
564 // Build a sequence of functions to get from iterator if possible.
565 ValueT *(concat_iterator::*GetHelperFns[])() const = {
566 &concat_iterator::getHelper<Ns>...};
567
568 // Loop over them, and return the first result we find.
569 for (auto &GetHelperFn : GetHelperFns)
570 if (ValueT *P = (this->*GetHelperFn)())
571 return *P;
572
573 llvm_unreachable("Attempted to get a pointer from an end concat iterator!")::llvm::llvm_unreachable_internal("Attempted to get a pointer from an end concat iterator!"
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ADT/STLExtras.h"
, 573)
;
574 }
575
576public:
577 /// Constructs an iterator from a squence of ranges.
578 ///
579 /// We need the full range to know how to switch between each of the
580 /// iterators.
581 template <typename... RangeTs>
582 explicit concat_iterator(RangeTs &&... Ranges)
583 : IterPairs({std::begin(Ranges), std::end(Ranges)}...) {}
584
585 using BaseT::operator++;
586
587 concat_iterator &operator++() {
588 increment(index_sequence_for<IterTs...>());
589 return *this;
590 }
591
592 ValueT &operator*() const { return get(index_sequence_for<IterTs...>()); }
593
594 bool operator==(const concat_iterator &RHS) const {
595 return IterPairs == RHS.IterPairs;
596 }
597};
598
599namespace detail {
600
601/// Helper to store a sequence of ranges being concatenated and access them.
602///
603/// This is designed to facilitate providing actual storage when temporaries
604/// are passed into the constructor such that we can use it as part of range
605/// based for loops.
606template <typename ValueT, typename... RangeTs> class concat_range {
607public:
608 using iterator =
609 concat_iterator<ValueT,
610 decltype(std::begin(std::declval<RangeTs &>()))...>;
611
612private:
613 std::tuple<RangeTs...> Ranges;
614
615 template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) {
616 return iterator(std::get<Ns>(Ranges)...);
617 }
618 template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) {
619 return iterator(make_range(std::end(std::get<Ns>(Ranges)),
620 std::end(std::get<Ns>(Ranges)))...);
621 }
622
623public:
624 concat_range(RangeTs &&... Ranges)
625 : Ranges(std::forward<RangeTs>(Ranges)...) {}
626
627 iterator begin() { return begin_impl(index_sequence_for<RangeTs...>{}); }
628 iterator end() { return end_impl(index_sequence_for<RangeTs...>{}); }
629};
630
631} // end namespace detail
632
633/// Concatenated range across two or more ranges.
634///
635/// The desired value type must be explicitly specified.
636template <typename ValueT, typename... RangeTs>
637detail::concat_range<ValueT, RangeTs...> concat(RangeTs &&... Ranges) {
638 static_assert(sizeof...(RangeTs) > 1,
639 "Need more than one range to concatenate!");
640 return detail::concat_range<ValueT, RangeTs...>(
641 std::forward<RangeTs>(Ranges)...);
642}
643
644//===----------------------------------------------------------------------===//
645// Extra additions to <utility>
646//===----------------------------------------------------------------------===//
647
648/// \brief Function object to check whether the first component of a std::pair
649/// compares less than the first component of another std::pair.
650struct less_first {
651 template <typename T> bool operator()(const T &lhs, const T &rhs) const {
652 return lhs.first < rhs.first;
653 }
654};
655
656/// \brief Function object to check whether the second component of a std::pair
657/// compares less than the second component of another std::pair.
658struct less_second {
659 template <typename T> bool operator()(const T &lhs, const T &rhs) const {
660 return lhs.second < rhs.second;
661 }
662};
663
664// A subset of N3658. More stuff can be added as-needed.
665
666/// \brief Represents a compile-time sequence of integers.
667template <class T, T... I> struct integer_sequence {
668 using value_type = T;
669
670 static constexpr size_t size() { return sizeof...(I); }
671};
672
673/// \brief Alias for the common case of a sequence of size_ts.
674template <size_t... I>
675struct index_sequence : integer_sequence<std::size_t, I...> {};
676
677template <std::size_t N, std::size_t... I>
678struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
679template <std::size_t... I>
680struct build_index_impl<0, I...> : index_sequence<I...> {};
681
682/// \brief Creates a compile-time integer sequence for a parameter pack.
683template <class... Ts>
684struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
685
686/// Utility type to build an inheritance chain that makes it easy to rank
687/// overload candidates.
688template <int N> struct rank : rank<N - 1> {};
689template <> struct rank<0> {};
690
691/// \brief traits class for checking whether type T is one of any of the given
692/// types in the variadic list.
693template <typename T, typename... Ts> struct is_one_of {
694 static const bool value = false;
695};
696
697template <typename T, typename U, typename... Ts>
698struct is_one_of<T, U, Ts...> {
699 static const bool value =
700 std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
701};
702
703/// \brief traits class for checking whether type T is a base class for all
704/// the given types in the variadic list.
705template <typename T, typename... Ts> struct are_base_of {
706 static const bool value = true;
707};
708
709template <typename T, typename U, typename... Ts>
710struct are_base_of<T, U, Ts...> {
711 static const bool value =
712 std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value;
713};
714
715//===----------------------------------------------------------------------===//
716// Extra additions for arrays
717//===----------------------------------------------------------------------===//
718
719/// Find the length of an array.
720template <class T, std::size_t N>
721constexpr inline size_t array_lengthof(T (&)[N]) {
722 return N;
723}
724
725/// Adapt std::less<T> for array_pod_sort.
726template<typename T>
727inline int array_pod_sort_comparator(const void *P1, const void *P2) {
728 if (std::less<T>()(*reinterpret_cast<const T*>(P1),
729 *reinterpret_cast<const T*>(P2)))
730 return -1;
731 if (std::less<T>()(*reinterpret_cast<const T*>(P2),
732 *reinterpret_cast<const T*>(P1)))
733 return 1;
734 return 0;
735}
736
737/// get_array_pod_sort_comparator - This is an internal helper function used to
738/// get type deduction of T right.
739template<typename T>
740inline int (*get_array_pod_sort_comparator(const T &))
741 (const void*, const void*) {
742 return array_pod_sort_comparator<T>;
743}
744
745/// array_pod_sort - This sorts an array with the specified start and end
746/// extent. This is just like std::sort, except that it calls qsort instead of
747/// using an inlined template. qsort is slightly slower than std::sort, but
748/// most sorts are not performance critical in LLVM and std::sort has to be
749/// template instantiated for each type, leading to significant measured code
750/// bloat. This function should generally be used instead of std::sort where
751/// possible.
752///
753/// This function assumes that you have simple POD-like types that can be
754/// compared with std::less and can be moved with memcpy. If this isn't true,
755/// you should use std::sort.
756///
757/// NOTE: If qsort_r were portable, we could allow a custom comparator and
758/// default to std::less.
759template<class IteratorTy>
760inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
761 // Don't inefficiently call qsort with one element or trigger undefined
762 // behavior with an empty sequence.
763 auto NElts = End - Start;
764 if (NElts <= 1) return;
765 qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
766}
767
768template <class IteratorTy>
769inline void array_pod_sort(
770 IteratorTy Start, IteratorTy End,
771 int (*Compare)(
772 const typename std::iterator_traits<IteratorTy>::value_type *,
773 const typename std::iterator_traits<IteratorTy>::value_type *)) {
774 // Don't inefficiently call qsort with one element or trigger undefined
775 // behavior with an empty sequence.
776 auto NElts = End - Start;
777 if (NElts <= 1) return;
778 qsort(&*Start, NElts, sizeof(*Start),
779 reinterpret_cast<int (*)(const void *, const void *)>(Compare));
780}
781
782//===----------------------------------------------------------------------===//
783// Extra additions to <algorithm>
784//===----------------------------------------------------------------------===//
785
786/// For a container of pointers, deletes the pointers and then clears the
787/// container.
788template<typename Container>
789void DeleteContainerPointers(Container &C) {
790 for (auto V : C)
791 delete V;
792 C.clear();
793}
794
795/// In a container of pairs (usually a map) whose second element is a pointer,
796/// deletes the second elements and then clears the container.
797template<typename Container>
798void DeleteContainerSeconds(Container &C) {
799 for (auto &V : C)
800 delete V.second;
801 C.clear();
802}
803
804/// Provide wrappers to std::for_each which take ranges instead of having to
805/// pass begin/end explicitly.
806template <typename R, typename UnaryPredicate>
807UnaryPredicate for_each(R &&Range, UnaryPredicate P) {
808 return std::for_each(adl_begin(Range), adl_end(Range), P);
809}
810
811/// Provide wrappers to std::all_of which take ranges instead of having to pass
812/// begin/end explicitly.
813template <typename R, typename UnaryPredicate>
814bool all_of(R &&Range, UnaryPredicate P) {
815 return std::all_of(adl_begin(Range), adl_end(Range), P);
816}
817
818/// Provide wrappers to std::any_of which take ranges instead of having to pass
819/// begin/end explicitly.
820template <typename R, typename UnaryPredicate>
821bool any_of(R &&Range, UnaryPredicate P) {
822 return std::any_of(adl_begin(Range), adl_end(Range), P);
823}
824
825/// Provide wrappers to std::none_of which take ranges instead of having to pass
826/// begin/end explicitly.
827template <typename R, typename UnaryPredicate>
828bool none_of(R &&Range, UnaryPredicate P) {
829 return std::none_of(adl_begin(Range), adl_end(Range), P);
830}
831
832/// Provide wrappers to std::find which take ranges instead of having to pass
833/// begin/end explicitly.
834template <typename R, typename T>
835auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) {
836 return std::find(adl_begin(Range), adl_end(Range), Val);
837}
838
839/// Provide wrappers to std::find_if which take ranges instead of having to pass
840/// begin/end explicitly.
841template <typename R, typename UnaryPredicate>
842auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
843 return std::find_if(adl_begin(Range), adl_end(Range), P);
844}
845
846template <typename R, typename UnaryPredicate>
847auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
848 return std::find_if_not(adl_begin(Range), adl_end(Range), P);
849}
850
851/// Provide wrappers to std::remove_if which take ranges instead of having to
852/// pass begin/end explicitly.
853template <typename R, typename UnaryPredicate>
854auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
855 return std::remove_if(adl_begin(Range), adl_end(Range), P);
856}
857
858/// Provide wrappers to std::copy_if which take ranges instead of having to
859/// pass begin/end explicitly.
860template <typename R, typename OutputIt, typename UnaryPredicate>
861OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
862 return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
863}
864
865template <typename R, typename OutputIt>
866OutputIt copy(R &&Range, OutputIt Out) {
867 return std::copy(adl_begin(Range), adl_end(Range), Out);
868}
869
870/// Wrapper function around std::find to detect if an element exists
871/// in a container.
872template <typename R, typename E>
873bool is_contained(R &&Range, const E &Element) {
874 return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
875}
876
877/// Wrapper function around std::count to count the number of times an element
878/// \p Element occurs in the given range \p Range.
879template <typename R, typename E>
880auto count(R &&Range, const E &Element) ->
881 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
882 return std::count(adl_begin(Range), adl_end(Range), Element);
883}
884
885/// Wrapper function around std::count_if to count the number of times an
886/// element satisfying a given predicate occurs in a range.
887template <typename R, typename UnaryPredicate>
888auto count_if(R &&Range, UnaryPredicate P) ->
889 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
890 return std::count_if(adl_begin(Range), adl_end(Range), P);
891}
892
893/// Wrapper function around std::transform to apply a function to a range and
894/// store the result elsewhere.
895template <typename R, typename OutputIt, typename UnaryPredicate>
896OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
897 return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
898}
899
900/// Provide wrappers to std::partition which take ranges instead of having to
901/// pass begin/end explicitly.
902template <typename R, typename UnaryPredicate>
903auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
904 return std::partition(adl_begin(Range), adl_end(Range), P);
905}
906
907/// Provide wrappers to std::lower_bound which take ranges instead of having to
908/// pass begin/end explicitly.
909template <typename R, typename ForwardIt>
910auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
911 return std::lower_bound(adl_begin(Range), adl_end(Range), I);
912}
913
914/// \brief Given a range of type R, iterate the entire range and return a
915/// SmallVector with elements of the vector. This is useful, for example,
916/// when you want to iterate a range and then sort the results.
917template <unsigned Size, typename R>
918SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size>
919to_vector(R &&Range) {
920 return {adl_begin(Range), adl_end(Range)};
921}
922
923/// Provide a container algorithm similar to C++ Library Fundamentals v2's
924/// `erase_if` which is equivalent to:
925///
926/// C.erase(remove_if(C, pred), C.end());
927///
928/// This version works for any container with an erase method call accepting
929/// two iterators.
930template <typename Container, typename UnaryPredicate>
931void erase_if(Container &C, UnaryPredicate P) {
932 C.erase(remove_if(C, P), C.end());
933}
934
935//===----------------------------------------------------------------------===//
936// Extra additions to <memory>
937//===----------------------------------------------------------------------===//
938
939// Implement make_unique according to N3656.
940
941/// \brief Constructs a `new T()` with the given args and returns a
942/// `unique_ptr<T>` which owns the object.
943///
944/// Example:
945///
946/// auto p = make_unique<int>();
947/// auto p = make_unique<std::tuple<int, int>>(0, 1);
948template <class T, class... Args>
949typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
950make_unique(Args &&... args) {
951 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
10
Calling 'forward'
11
Returning from 'forward'
12
Calling constructor for 'CoverageMapError'
18
Returning from constructor for 'CoverageMapError'
952}
953
954/// \brief Constructs a `new T[n]` with the given args and returns a
955/// `unique_ptr<T[]>` which owns the object.
956///
957/// \param n size of the new array.
958///
959/// Example:
960///
961/// auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
962template <class T>
963typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
964 std::unique_ptr<T>>::type
965make_unique(size_t n) {
966 return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
967}
968
969/// This function isn't used and is only here to provide better compile errors.
970template <class T, class... Args>
971typename std::enable_if<std::extent<T>::value != 0>::type
972make_unique(Args &&...) = delete;
973
974struct FreeDeleter {
975 void operator()(void* v) {
976 ::free(v);
977 }
978};
979
980template<typename First, typename Second>
981struct pair_hash {
982 size_t operator()(const std::pair<First, Second> &P) const {
983 return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
984 }
985};
986
987/// A functor like C++14's std::less<void> in its absence.
988struct less {
989 template <typename A, typename B> bool operator()(A &&a, B &&b) const {
990 return std::forward<A>(a) < std::forward<B>(b);
991 }
992};
993
994/// A functor like C++14's std::equal<void> in its absence.
995struct equal {
996 template <typename A, typename B> bool operator()(A &&a, B &&b) const {
997 return std::forward<A>(a) == std::forward<B>(b);
998 }
999};
1000
1001/// Binary functor that adapts to any other binary functor after dereferencing
1002/// operands.
1003template <typename T> struct deref {
1004 T func;
1005
1006 // Could be further improved to cope with non-derivable functors and
1007 // non-binary functors (should be a variadic template member function
1008 // operator()).
1009 template <typename A, typename B>
1010 auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
1011 assert(lhs)(static_cast <bool> (lhs) ? void (0) : __assert_fail ("lhs"
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ADT/STLExtras.h"
, 1011, __extension__ __PRETTY_FUNCTION__))
;
1012 assert(rhs)(static_cast <bool> (rhs) ? void (0) : __assert_fail ("rhs"
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ADT/STLExtras.h"
, 1012, __extension__ __PRETTY_FUNCTION__))
;
1013 return func(*lhs, *rhs);
1014 }
1015};
1016
1017namespace detail {
1018
1019template <typename R> class enumerator_iter;
1020
1021template <typename R> struct result_pair {
1022 friend class enumerator_iter<R>;
1023
1024 result_pair() = default;
1025 result_pair(std::size_t Index, IterOfRange<R> Iter)
1026 : Index(Index), Iter(Iter) {}
1027
1028 result_pair<R> &operator=(const result_pair<R> &Other) {
1029 Index = Other.Index;
1030 Iter = Other.Iter;
1031 return *this;
1032 }
1033
1034 std::size_t index() const { return Index; }
1035 const ValueOfRange<R> &value() const { return *Iter; }
1036 ValueOfRange<R> &value() { return *Iter; }
1037
1038private:
1039 std::size_t Index = std::numeric_limits<std::size_t>::max();
1040 IterOfRange<R> Iter;
1041};
1042
1043template <typename R>
1044class enumerator_iter
1045 : public iterator_facade_base<
1046 enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,
1047 typename std::iterator_traits<IterOfRange<R>>::difference_type,
1048 typename std::iterator_traits<IterOfRange<R>>::pointer,
1049 typename std::iterator_traits<IterOfRange<R>>::reference> {
1050 using result_type = result_pair<R>;
1051
1052public:
1053 explicit enumerator_iter(IterOfRange<R> EndIter)
1054 : Result(std::numeric_limits<size_t>::max(), EndIter) {}
1055
1056 enumerator_iter(std::size_t Index, IterOfRange<R> Iter)
1057 : Result(Index, Iter) {}
1058
1059 result_type &operator*() { return Result; }
1060 const result_type &operator*() const { return Result; }
1061
1062 enumerator_iter<R> &operator++() {
1063 assert(Result.Index != std::numeric_limits<size_t>::max())(static_cast <bool> (Result.Index != std::numeric_limits
<size_t>::max()) ? void (0) : __assert_fail ("Result.Index != std::numeric_limits<size_t>::max()"
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ADT/STLExtras.h"
, 1063, __extension__ __PRETTY_FUNCTION__))
;
1064 ++Result.Iter;
1065 ++Result.Index;
1066 return *this;
1067 }
1068
1069 bool operator==(const enumerator_iter<R> &RHS) const {
1070 // Don't compare indices here, only iterators. It's possible for an end
1071 // iterator to have different indices depending on whether it was created
1072 // by calling std::end() versus incrementing a valid iterator.
1073 return Result.Iter == RHS.Result.Iter;
1074 }
1075
1076 enumerator_iter<R> &operator=(const enumerator_iter<R> &Other) {
1077 Result = Other.Result;
1078 return *this;
1079 }
1080
1081private:
1082 result_type Result;
1083};
1084
1085template <typename R> class enumerator {
1086public:
1087 explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
1088
1089 enumerator_iter<R> begin() {
1090 return enumerator_iter<R>(0, std::begin(TheRange));
1091 }
1092
1093 enumerator_iter<R> end() {
1094 return enumerator_iter<R>(std::end(TheRange));
1095 }
1096
1097private:
1098 R TheRange;
1099};
1100
1101} // end namespace detail
1102
1103/// Given an input range, returns a new range whose values are are pair (A,B)
1104/// such that A is the 0-based index of the item in the sequence, and B is
1105/// the value from the original sequence. Example:
1106///
1107/// std::vector<char> Items = {'A', 'B', 'C', 'D'};
1108/// for (auto X : enumerate(Items)) {
1109/// printf("Item %d - %c\n", X.index(), X.value());
1110/// }
1111///
1112/// Output:
1113/// Item 0 - A
1114/// Item 1 - B
1115/// Item 2 - C
1116/// Item 3 - D
1117///
1118template <typename R> detail::enumerator<R> enumerate(R &&TheRange) {
1119 return detail::enumerator<R>(std::forward<R>(TheRange));
1120}
1121
1122namespace detail {
1123
1124template <typename F, typename Tuple, std::size_t... I>
1125auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence<I...>)
1126 -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) {
1127 return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
1128}
1129
1130} // end namespace detail
1131
1132/// Given an input tuple (a1, a2, ..., an), pass the arguments of the
1133/// tuple variadically to f as if by calling f(a1, a2, ..., an) and
1134/// return the result.
1135template <typename F, typename Tuple>
1136auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
1137 std::forward<F>(f), std::forward<Tuple>(t),
1138 build_index_impl<
1139 std::tuple_size<typename std::decay<Tuple>::type>::value>{})) {
1140 using Indices = build_index_impl<
1141 std::tuple_size<typename std::decay<Tuple>::type>::value>;
1142
1143 return detail::apply_tuple_impl(std::forward<F>(f), std::forward<Tuple>(t),
1144 Indices{});
1145}
1146
1147} // end namespace llvm
1148
1149#endif // LLVM_ADT_STLEXTRAS_H

/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ProfileData/Coverage/CoverageMapping.h

1//===- CoverageMapping.h - Code coverage mapping support --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Code coverage mapping data is generated by clang and read by
11// llvm-cov to show code coverage statistics for a file.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
16#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
17
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/Hashing.h"
21#include "llvm/ADT/None.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/ADT/StringSet.h"
24#include "llvm/ADT/iterator.h"
25#include "llvm/ADT/iterator_range.h"
26#include "llvm/ProfileData/InstrProf.h"
27#include "llvm/Support/Compiler.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/Endian.h"
30#include "llvm/Support/Error.h"
31#include "llvm/Support/raw_ostream.h"
32#include <cassert>
33#include <cstdint>
34#include <iterator>
35#include <memory>
36#include <string>
37#include <system_error>
38#include <tuple>
39#include <utility>
40#include <vector>
41
42namespace llvm {
43
44class IndexedInstrProfReader;
45
46namespace coverage {
47
48class CoverageMappingReader;
49struct CoverageMappingRecord;
50
51enum class coveragemap_error {
52 success = 0,
53 eof,
54 no_data_found,
55 unsupported_version,
56 truncated,
57 malformed
58};
59
60const std::error_category &coveragemap_category();
61
62inline std::error_code make_error_code(coveragemap_error E) {
63 return std::error_code(static_cast<int>(E), coveragemap_category());
64}
65
66class CoverageMapError : public ErrorInfo<CoverageMapError> {
67public:
68 CoverageMapError(coveragemap_error Err) : Err(Err) {
13
Calling implicit default constructor for 'ErrorInfo'
14
Calling implicit default constructor for 'ErrorInfoBase'
15
Returning from default constructor for 'ErrorInfoBase'
16
Returning from default constructor for 'ErrorInfo'
69 assert(Err != coveragemap_error::success && "Not an error")(static_cast <bool> (Err != coveragemap_error::success &&
"Not an error") ? void (0) : __assert_fail ("Err != coveragemap_error::success && \"Not an error\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ProfileData/Coverage/CoverageMapping.h"
, 69, __extension__ __PRETTY_FUNCTION__))
;
17
Within the expansion of the macro 'assert':
70 }
71
72 std::string message() const override;
73
74 void log(raw_ostream &OS) const override { OS << message(); }
75
76 std::error_code convertToErrorCode() const override {
77 return make_error_code(Err);
78 }
79
80 coveragemap_error get() const { return Err; }
81
82 static char ID;
83
84private:
85 coveragemap_error Err;
86};
87
88/// A Counter is an abstract value that describes how to compute the
89/// execution count for a region of code using the collected profile count data.
90struct Counter {
91 enum CounterKind { Zero, CounterValueReference, Expression };
92 static const unsigned EncodingTagBits = 2;
93 static const unsigned EncodingTagMask = 0x3;
94 static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
95 EncodingTagBits + 1;
96
97private:
98 CounterKind Kind = Zero;
99 unsigned ID = 0;
100
101 Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
102
103public:
104 Counter() = default;
105
106 CounterKind getKind() const { return Kind; }
107
108 bool isZero() const { return Kind == Zero; }
109
110 bool isExpression() const { return Kind == Expression; }
111
112 unsigned getCounterID() const { return ID; }
113
114 unsigned getExpressionID() const { return ID; }
115
116 friend bool operator==(const Counter &LHS, const Counter &RHS) {
117 return LHS.Kind == RHS.Kind && LHS.ID == RHS.ID;
118 }
119
120 friend bool operator!=(const Counter &LHS, const Counter &RHS) {
121 return !(LHS == RHS);
122 }
123
124 friend bool operator<(const Counter &LHS, const Counter &RHS) {
125 return std::tie(LHS.Kind, LHS.ID) < std::tie(RHS.Kind, RHS.ID);
126 }
127
128 /// Return the counter that represents the number zero.
129 static Counter getZero() { return Counter(); }
130
131 /// Return the counter that corresponds to a specific profile counter.
132 static Counter getCounter(unsigned CounterId) {
133 return Counter(CounterValueReference, CounterId);
134 }
135
136 /// Return the counter that corresponds to a specific addition counter
137 /// expression.
138 static Counter getExpression(unsigned ExpressionId) {
139 return Counter(Expression, ExpressionId);
140 }
141};
142
143/// A Counter expression is a value that represents an arithmetic operation
144/// with two counters.
145struct CounterExpression {
146 enum ExprKind { Subtract, Add };
147 ExprKind Kind;
148 Counter LHS, RHS;
149
150 CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
151 : Kind(Kind), LHS(LHS), RHS(RHS) {}
152};
153
154/// A Counter expression builder is used to construct the counter expressions.
155/// It avoids unnecessary duplication and simplifies algebraic expressions.
156class CounterExpressionBuilder {
157 /// A list of all the counter expressions
158 std::vector<CounterExpression> Expressions;
159
160 /// A lookup table for the index of a given expression.
161 DenseMap<CounterExpression, unsigned> ExpressionIndices;
162
163 /// Return the counter which corresponds to the given expression.
164 ///
165 /// If the given expression is already stored in the builder, a counter
166 /// that references that expression is returned. Otherwise, the given
167 /// expression is added to the builder's collection of expressions.
168 Counter get(const CounterExpression &E);
169
170 /// Represents a term in a counter expression tree.
171 struct Term {
172 unsigned CounterID;
173 int Factor;
174
175 Term(unsigned CounterID, int Factor)
176 : CounterID(CounterID), Factor(Factor) {}
177 };
178
179 /// Gather the terms of the expression tree for processing.
180 ///
181 /// This collects each addition and subtraction referenced by the counter into
182 /// a sequence that can be sorted and combined to build a simplified counter
183 /// expression.
184 void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
185
186 /// Simplifies the given expression tree
187 /// by getting rid of algebraically redundant operations.
188 Counter simplify(Counter ExpressionTree);
189
190public:
191 ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
192
193 /// Return a counter that represents the expression that adds LHS and RHS.
194 Counter add(Counter LHS, Counter RHS);
195
196 /// Return a counter that represents the expression that subtracts RHS from
197 /// LHS.
198 Counter subtract(Counter LHS, Counter RHS);
199};
200
201using LineColPair = std::pair<unsigned, unsigned>;
202
203/// A Counter mapping region associates a source range with a specific counter.
204struct CounterMappingRegion {
205 enum RegionKind {
206 /// A CodeRegion associates some code with a counter
207 CodeRegion,
208
209 /// An ExpansionRegion represents a file expansion region that associates
210 /// a source range with the expansion of a virtual source file, such as
211 /// for a macro instantiation or #include file.
212 ExpansionRegion,
213
214 /// A SkippedRegion represents a source range with code that was skipped
215 /// by a preprocessor or similar means.
216 SkippedRegion,
217
218 /// A GapRegion is like a CodeRegion, but its count is only set as the
219 /// line execution count when its the only region in the line.
220 GapRegion
221 };
222
223 Counter Count;
224 unsigned FileID, ExpandedFileID;
225 unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
226 RegionKind Kind;
227
228 CounterMappingRegion(Counter Count, unsigned FileID, unsigned ExpandedFileID,
229 unsigned LineStart, unsigned ColumnStart,
230 unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
231 : Count(Count), FileID(FileID), ExpandedFileID(ExpandedFileID),
232 LineStart(LineStart), ColumnStart(ColumnStart), LineEnd(LineEnd),
233 ColumnEnd(ColumnEnd), Kind(Kind) {}
234
235 static CounterMappingRegion
236 makeRegion(Counter Count, unsigned FileID, unsigned LineStart,
237 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
238 return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
239 LineEnd, ColumnEnd, CodeRegion);
240 }
241
242 static CounterMappingRegion
243 makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
244 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
245 return CounterMappingRegion(Counter(), FileID, ExpandedFileID, LineStart,
246 ColumnStart, LineEnd, ColumnEnd,
247 ExpansionRegion);
248 }
249
250 static CounterMappingRegion
251 makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
252 unsigned LineEnd, unsigned ColumnEnd) {
253 return CounterMappingRegion(Counter(), FileID, 0, LineStart, ColumnStart,
254 LineEnd, ColumnEnd, SkippedRegion);
255 }
256
257 static CounterMappingRegion
258 makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart,
259 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
260 return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
261 LineEnd, (1U << 31) | ColumnEnd, GapRegion);
262 }
263
264 inline LineColPair startLoc() const {
265 return LineColPair(LineStart, ColumnStart);
266 }
267
268 inline LineColPair endLoc() const { return LineColPair(LineEnd, ColumnEnd); }
269};
270
271/// Associates a source range with an execution count.
272struct CountedRegion : public CounterMappingRegion {
273 uint64_t ExecutionCount;
274
275 CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
276 : CounterMappingRegion(R), ExecutionCount(ExecutionCount) {}
277};
278
279/// A Counter mapping context is used to connect the counters, expressions
280/// and the obtained counter values.
281class CounterMappingContext {
282 ArrayRef<CounterExpression> Expressions;
283 ArrayRef<uint64_t> CounterValues;
284
285public:
286 CounterMappingContext(ArrayRef<CounterExpression> Expressions,
287 ArrayRef<uint64_t> CounterValues = None)
288 : Expressions(Expressions), CounterValues(CounterValues) {}
289
290 void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
291
292 void dump(const Counter &C, raw_ostream &OS) const;
293 void dump(const Counter &C) const { dump(C, dbgs()); }
294
295 /// Return the number of times that a region of code associated with this
296 /// counter was executed.
297 Expected<int64_t> evaluate(const Counter &C) const;
298};
299
300/// Code coverage information for a single function.
301struct FunctionRecord {
302 /// Raw function name.
303 std::string Name;
304 /// Associated files.
305 std::vector<std::string> Filenames;
306 /// Regions in the function along with their counts.
307 std::vector<CountedRegion> CountedRegions;
308 /// The number of times this function was executed.
309 uint64_t ExecutionCount;
310
311 FunctionRecord(StringRef Name, ArrayRef<StringRef> Filenames)
312 : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
313
314 FunctionRecord(FunctionRecord &&FR) = default;
315 FunctionRecord &operator=(FunctionRecord &&) = default;
316
317 void pushRegion(CounterMappingRegion Region, uint64_t Count) {
318 if (CountedRegions.empty())
319 ExecutionCount = Count;
320 CountedRegions.emplace_back(Region, Count);
321 }
322};
323
324/// Iterator over Functions, optionally filtered to a single file.
325class FunctionRecordIterator
326 : public iterator_facade_base<FunctionRecordIterator,
327 std::forward_iterator_tag, FunctionRecord> {
328 ArrayRef<FunctionRecord> Records;
329 ArrayRef<FunctionRecord>::iterator Current;
330 StringRef Filename;
331
332 /// Skip records whose primary file is not \c Filename.
333 void skipOtherFiles();
334
335public:
336 FunctionRecordIterator(ArrayRef<FunctionRecord> Records_,
337 StringRef Filename = "")
338 : Records(Records_), Current(Records.begin()), Filename(Filename) {
339 skipOtherFiles();
340 }
341
342 FunctionRecordIterator() : Current(Records.begin()) {}
343
344 bool operator==(const FunctionRecordIterator &RHS) const {
345 return Current == RHS.Current && Filename == RHS.Filename;
346 }
347
348 const FunctionRecord &operator*() const { return *Current; }
349
350 FunctionRecordIterator &operator++() {
351 assert(Current != Records.end() && "incremented past end")(static_cast <bool> (Current != Records.end() &&
"incremented past end") ? void (0) : __assert_fail ("Current != Records.end() && \"incremented past end\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ProfileData/Coverage/CoverageMapping.h"
, 351, __extension__ __PRETTY_FUNCTION__))
;
352 ++Current;
353 skipOtherFiles();
354 return *this;
355 }
356};
357
358/// Coverage information for a macro expansion or #included file.
359///
360/// When covered code has pieces that can be expanded for more detail, such as a
361/// preprocessor macro use and its definition, these are represented as
362/// expansions whose coverage can be looked up independently.
363struct ExpansionRecord {
364 /// The abstract file this expansion covers.
365 unsigned FileID;
366 /// The region that expands to this record.
367 const CountedRegion &Region;
368 /// Coverage for the expansion.
369 const FunctionRecord &Function;
370
371 ExpansionRecord(const CountedRegion &Region,
372 const FunctionRecord &Function)
373 : FileID(Region.ExpandedFileID), Region(Region), Function(Function) {}
374};
375
376/// The execution count information starting at a point in a file.
377///
378/// A sequence of CoverageSegments gives execution counts for a file in format
379/// that's simple to iterate through for processing.
380struct CoverageSegment {
381 /// The line where this segment begins.
382 unsigned Line;
383 /// The column where this segment begins.
384 unsigned Col;
385 /// The execution count, or zero if no count was recorded.
386 uint64_t Count;
387 /// When false, the segment was uninstrumented or skipped.
388 bool HasCount;
389 /// Whether this enters a new region or returns to a previous count.
390 bool IsRegionEntry;
391 /// Whether this enters a gap region.
392 bool IsGapRegion;
393
394 CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
395 : Line(Line), Col(Col), Count(0), HasCount(false),
396 IsRegionEntry(IsRegionEntry), IsGapRegion(false) {}
397
398 CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
399 bool IsRegionEntry, bool IsGapRegion = false)
400 : Line(Line), Col(Col), Count(Count), HasCount(true),
401 IsRegionEntry(IsRegionEntry), IsGapRegion(IsGapRegion) {}
402
403 friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
404 return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
405 L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
406 R.HasCount, R.IsRegionEntry,
407 R.IsGapRegion);
408 }
409};
410
411/// An instantiation group contains a \c FunctionRecord list, such that each
412/// record corresponds to a distinct instantiation of the same function.
413///
414/// Note that it's possible for a function to have more than one instantiation
415/// (consider C++ template specializations or static inline functions).
416class InstantiationGroup {
417 friend class CoverageMapping;
418
419 unsigned Line;
420 unsigned Col;
421 std::vector<const FunctionRecord *> Instantiations;
422
423 InstantiationGroup(unsigned Line, unsigned Col,
424 std::vector<const FunctionRecord *> Instantiations)
425 : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
426
427public:
428 InstantiationGroup(const InstantiationGroup &) = delete;
429 InstantiationGroup(InstantiationGroup &&) = default;
430
431 /// Get the number of instantiations in this group.
432 size_t size() const { return Instantiations.size(); }
433
434 /// Get the line where the common function was defined.
435 unsigned getLine() const { return Line; }
436
437 /// Get the column where the common function was defined.
438 unsigned getColumn() const { return Col; }
439
440 /// Check if the instantiations in this group have a common mangled name.
441 bool hasName() const {
442 for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
443 if (Instantiations[I]->Name != Instantiations[0]->Name)
444 return false;
445 return true;
446 }
447
448 /// Get the common mangled name for instantiations in this group.
449 StringRef getName() const {
450 assert(hasName() && "Instantiations don't have a shared name")(static_cast <bool> (hasName() && "Instantiations don't have a shared name"
) ? void (0) : __assert_fail ("hasName() && \"Instantiations don't have a shared name\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/ProfileData/Coverage/CoverageMapping.h"
, 450, __extension__ __PRETTY_FUNCTION__))
;
451 return Instantiations[0]->Name;
452 }
453
454 /// Get the total execution count of all instantiations in this group.
455 uint64_t getTotalExecutionCount() const {
456 uint64_t Count = 0;
457 for (const FunctionRecord *F : Instantiations)
458 Count += F->ExecutionCount;
459 return Count;
460 }
461
462 /// Get the instantiations in this group.
463 ArrayRef<const FunctionRecord *> getInstantiations() const {
464 return Instantiations;
465 }
466};
467
468/// Coverage information to be processed or displayed.
469///
470/// This represents the coverage of an entire file, expansion, or function. It
471/// provides a sequence of CoverageSegments to iterate through, as well as the
472/// list of expansions that can be further processed.
473class CoverageData {
474 friend class CoverageMapping;
475
476 std::string Filename;
477 std::vector<CoverageSegment> Segments;
478 std::vector<ExpansionRecord> Expansions;
479
480public:
481 CoverageData() = default;
482
483 CoverageData(StringRef Filename) : Filename(Filename) {}
484
485 /// Get the name of the file this data covers.
486 StringRef getFilename() const { return Filename; }
487
488 /// Get an iterator over the coverage segments for this object. The segments
489 /// are guaranteed to be uniqued and sorted by location.
490 std::vector<CoverageSegment>::const_iterator begin() const {
491 return Segments.begin();
492 }
493
494 std::vector<CoverageSegment>::const_iterator end() const {
495 return Segments.end();
496 }
497
498 bool empty() const { return Segments.empty(); }
499
500 /// Expansions that can be further processed.
501 ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
502};
503
504/// The mapping of profile information to coverage data.
505///
506/// This is the main interface to get coverage information, using a profile to
507/// fill out execution counts.
508class CoverageMapping {
509 StringSet<> FunctionNames;
510 std::vector<FunctionRecord> Functions;
511 std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
512 std::vector<std::pair<std::string, uint64_t>> FuncCounterMismatches;
513
514 CoverageMapping() = default;
515
516 /// Add a function record corresponding to \p Record.
517 Error loadFunctionRecord(const CoverageMappingRecord &Record,
518 IndexedInstrProfReader &ProfileReader);
519
520public:
521 CoverageMapping(const CoverageMapping &) = delete;
522 CoverageMapping &operator=(const CoverageMapping &) = delete;
523
524 /// Load the coverage mapping using the given readers.
525 static Expected<std::unique_ptr<CoverageMapping>>
526 load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
527 IndexedInstrProfReader &ProfileReader);
528
529 /// Load the coverage mapping from the given object files and profile. If
530 /// \p Arches is non-empty, it must specify an architecture for each object.
531 static Expected<std::unique_ptr<CoverageMapping>>
532 load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
533 ArrayRef<StringRef> Arches = None);
534
535 /// The number of functions that couldn't have their profiles mapped.
536 ///
537 /// This is a count of functions whose profile is out of date or otherwise
538 /// can't be associated with any coverage information.
539 unsigned getMismatchedCount() const {
540 return FuncHashMismatches.size() + FuncCounterMismatches.size();
541 }
542
543 /// A hash mismatch occurs when a profile record for a symbol does not have
544 /// the same hash as a coverage mapping record for the same symbol. This
545 /// returns a list of hash mismatches, where each mismatch is a pair of the
546 /// symbol name and its coverage mapping hash.
547 ArrayRef<std::pair<std::string, uint64_t>> getHashMismatches() const {
548 return FuncHashMismatches;
549 }
550
551 /// A counter mismatch occurs when there is an error when evaluating the
552 /// counter expressions in a coverage mapping record. This returns a list of
553 /// counter mismatches, where each mismatch is a pair of the symbol name and
554 /// the number of valid evaluated counter expressions.
555 ArrayRef<std::pair<std::string, uint64_t>> getCounterMismatches() const {
556 return FuncCounterMismatches;
557 }
558
559 /// Returns a lexicographically sorted, unique list of files that are
560 /// covered.
561 std::vector<StringRef> getUniqueSourceFiles() const;
562
563 /// Get the coverage for a particular file.
564 ///
565 /// The given filename must be the name as recorded in the coverage
566 /// information. That is, only names returned from getUniqueSourceFiles will
567 /// yield a result.
568 CoverageData getCoverageForFile(StringRef Filename) const;
569
570 /// Get the coverage for a particular function.
571 CoverageData getCoverageForFunction(const FunctionRecord &Function) const;
572
573 /// Get the coverage for an expansion within a coverage set.
574 CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion) const;
575
576 /// Gets all of the functions covered by this profile.
577 iterator_range<FunctionRecordIterator> getCoveredFunctions() const {
578 return make_range(FunctionRecordIterator(Functions),
579 FunctionRecordIterator());
580 }
581
582 /// Gets all of the functions in a particular file.
583 iterator_range<FunctionRecordIterator>
584 getCoveredFunctions(StringRef Filename) const {
585 return make_range(FunctionRecordIterator(Functions, Filename),
586 FunctionRecordIterator());
587 }
588
589 /// Get the list of function instantiation groups in a particular file.
590 ///
591 /// Every instantiation group in a program is attributed to exactly one file:
592 /// the file in which the definition for the common function begins.
593 std::vector<InstantiationGroup>
594 getInstantiationGroups(StringRef Filename) const;
595};
596
597/// Coverage statistics for a single line.
598class LineCoverageStats {
599 uint64_t ExecutionCount;
600 bool HasMultipleRegions;
601 bool Mapped;
602 unsigned Line;
603 ArrayRef<const CoverageSegment *> LineSegments;
604 const CoverageSegment *WrappedSegment;
605
606 friend class LineCoverageIterator;
607 LineCoverageStats() = default;
608
609public:
610 LineCoverageStats(ArrayRef<const CoverageSegment *> LineSegments,
611 const CoverageSegment *WrappedSegment, unsigned Line);
612
613 uint64_t getExecutionCount() const { return ExecutionCount; }
614
615 bool hasMultipleRegions() const { return HasMultipleRegions; }
616
617 bool isMapped() const { return Mapped; }
618
619 unsigned getLine() const { return Line; }
620
621 ArrayRef<const CoverageSegment *> getLineSegments() const {
622 return LineSegments;
623 }
624
625 const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
626};
627
628/// An iterator over the \c LineCoverageStats objects for lines described by
629/// a \c CoverageData instance.
630class LineCoverageIterator
631 : public iterator_facade_base<
632 LineCoverageIterator, std::forward_iterator_tag, LineCoverageStats> {
633public:
634 LineCoverageIterator(const CoverageData &CD)
635 : LineCoverageIterator(CD, CD.begin()->Line) {}
636
637 LineCoverageIterator(const CoverageData &CD, unsigned Line)
638 : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
639 Line(Line), Segments(), Stats() {
640 this->operator++();
641 }
642
643 LineCoverageIterator &operator=(const LineCoverageIterator &R) = default;
644
645 bool operator==(const LineCoverageIterator &R) const {
646 return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
647 }
648
649 const LineCoverageStats &operator*() const { return Stats; }
650
651 LineCoverageStats &operator*() { return Stats; }
652
653 LineCoverageIterator &operator++();
654
655 LineCoverageIterator getEnd() const {
656 auto EndIt = *this;
657 EndIt.Next = CD.end();
658 EndIt.Ended = true;
659 return EndIt;
660 }
661
662private:
663 const CoverageData &CD;
664 const CoverageSegment *WrappedSegment;
665 std::vector<CoverageSegment>::const_iterator Next;
666 bool Ended;
667 unsigned Line;
668 SmallVector<const CoverageSegment *, 4> Segments;
669 LineCoverageStats Stats;
670};
671
672/// Get a \c LineCoverageIterator range for the lines described by \p CD.
673static inline iterator_range<LineCoverageIterator>
674getLineCoverageStats(const coverage::CoverageData &CD) {
675 auto Begin = LineCoverageIterator(CD);
676 auto End = Begin.getEnd();
677 return make_range(Begin, End);
678}
679
680// Profile coverage map has the following layout:
681// [CoverageMapFileHeader]
682// [ArrayStart]
683// [CovMapFunctionRecord]
684// [CovMapFunctionRecord]
685// ...
686// [ArrayEnd]
687// [Encoded Region Mapping Data]
688LLVM_PACKED_STARTpack(push, 1)
689template <class IntPtrT> struct CovMapFunctionRecordV1 {
690#define COVMAP_V1
691#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
692#include "llvm/ProfileData/InstrProfData.inc"
693#undef COVMAP_V1
694
695 // Return the structural hash associated with the function.
696 template <support::endianness Endian> uint64_t getFuncHash() const {
697 return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
698 }
699
700 // Return the coverage map data size for the funciton.
701 template <support::endianness Endian> uint32_t getDataSize() const {
702 return support::endian::byte_swap<uint32_t, Endian>(DataSize);
703 }
704
705 // Return function lookup key. The value is consider opaque.
706 template <support::endianness Endian> IntPtrT getFuncNameRef() const {
707 return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
708 }
709
710 // Return the PGO name of the function */
711 template <support::endianness Endian>
712 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
713 IntPtrT NameRef = getFuncNameRef<Endian>();
714 uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
715 FuncName = ProfileNames.getFuncName(NameRef, NameS);
716 if (NameS && FuncName.empty())
717 return make_error<CoverageMapError>(coveragemap_error::malformed);
718 return Error::success();
719 }
720};
721
722struct CovMapFunctionRecord {
723#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
724#include "llvm/ProfileData/InstrProfData.inc"
725
726 // Return the structural hash associated with the function.
727 template <support::endianness Endian> uint64_t getFuncHash() const {
728 return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
729 }
730
731 // Return the coverage map data size for the funciton.
732 template <support::endianness Endian> uint32_t getDataSize() const {
733 return support::endian::byte_swap<uint32_t, Endian>(DataSize);
734 }
735
736 // Return function lookup key. The value is consider opaque.
737 template <support::endianness Endian> uint64_t getFuncNameRef() const {
738 return support::endian::byte_swap<uint64_t, Endian>(NameRef);
739 }
740
741 // Return the PGO name of the function */
742 template <support::endianness Endian>
743 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
744 uint64_t NameRef = getFuncNameRef<Endian>();
745 FuncName = ProfileNames.getFuncName(NameRef);
746 return Error::success();
747 }
748};
749
750// Per module coverage mapping data header, i.e. CoverageMapFileHeader
751// documented above.
752struct CovMapHeader {
753#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
754#include "llvm/ProfileData/InstrProfData.inc"
755 template <support::endianness Endian> uint32_t getNRecords() const {
756 return support::endian::byte_swap<uint32_t, Endian>(NRecords);
757 }
758
759 template <support::endianness Endian> uint32_t getFilenamesSize() const {
760 return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
761 }
762
763 template <support::endianness Endian> uint32_t getCoverageSize() const {
764 return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
765 }
766
767 template <support::endianness Endian> uint32_t getVersion() const {
768 return support::endian::byte_swap<uint32_t, Endian>(Version);
769 }
770};
771
772LLVM_PACKED_ENDpack(pop)
773
774enum CovMapVersion {
775 Version1 = 0,
776 // Function's name reference from CovMapFuncRecord is changed from raw
777 // name string pointer to MD5 to support name section compression. Name
778 // section is also compressed.
779 Version2 = 1,
780 // A new interpretation of the columnEnd field is added in order to mark
781 // regions as gap areas.
782 Version3 = 2,
783 // The current version is Version3
784 CurrentVersion = INSTR_PROF_COVMAP_VERSION2
785};
786
787template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
788 using CovMapFuncRecordType = CovMapFunctionRecord;
789 using NameRefType = uint64_t;
790};
791
792template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
793 using CovMapFuncRecordType = CovMapFunctionRecordV1<IntPtrT>;
794 using NameRefType = IntPtrT;
795};
796
797} // end namespace coverage
798
799/// Provide DenseMapInfo for CounterExpression
800template<> struct DenseMapInfo<coverage::CounterExpression> {
801 static inline coverage::CounterExpression getEmptyKey() {
802 using namespace coverage;
803
804 return CounterExpression(CounterExpression::ExprKind::Subtract,
805 Counter::getCounter(~0U),
806 Counter::getCounter(~0U));
807 }
808
809 static inline coverage::CounterExpression getTombstoneKey() {
810 using namespace coverage;
811
812 return CounterExpression(CounterExpression::ExprKind::Add,
813 Counter::getCounter(~0U),
814 Counter::getCounter(~0U));
815 }
816
817 static unsigned getHashValue(const coverage::CounterExpression &V) {
818 return static_cast<unsigned>(
819 hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
820 V.RHS.getKind(), V.RHS.getCounterID()));
821 }
822
823 static bool isEqual(const coverage::CounterExpression &LHS,
824 const coverage::CounterExpression &RHS) {
825 return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
826 }
827};
828
829} // end namespace llvm
830
831#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H