Bug Summary

File:include/llvm/Support/Error.h
Warning:line 201, column 5
Potential leak of memory pointed to by 'Payload._M_t._M_head_impl'

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 ResourceFileWriter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/llvm-rc -I /build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.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-8~svn345461/build-llvm/tools/llvm-rc -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp

1//===-- ResourceFileWriter.cpp --------------------------------*- 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 implements the visitor serializing resources to a .res stream.
11//
12//===---------------------------------------------------------------------===//
13
14#include "ResourceFileWriter.h"
15
16#include "llvm/Object/WindowsResource.h"
17#include "llvm/Support/ConvertUTF.h"
18#include "llvm/Support/Endian.h"
19#include "llvm/Support/EndianStream.h"
20#include "llvm/Support/MemoryBuffer.h"
21#include "llvm/Support/Path.h"
22#include "llvm/Support/Process.h"
23
24using namespace llvm::support;
25
26// Take an expression returning llvm::Error and forward the error if it exists.
27#define RETURN_IF_ERROR(Expr)if (auto Err = (Expr)) return Err; \
28 if (auto Err = (Expr)) \
29 return Err;
30
31namespace llvm {
32namespace rc {
33
34// Class that employs RAII to save the current FileWriter object state
35// and revert to it as soon as we leave the scope. This is useful if resources
36// declare their own resource-local statements.
37class ContextKeeper {
38 ResourceFileWriter *FileWriter;
39 ResourceFileWriter::ObjectInfo SavedInfo;
40
41public:
42 ContextKeeper(ResourceFileWriter *V)
43 : FileWriter(V), SavedInfo(V->ObjectData) {}
44 ~ContextKeeper() { FileWriter->ObjectData = SavedInfo; }
45};
46
47static Error createError(const Twine &Message,
48 std::errc Type = std::errc::invalid_argument) {
49 return make_error<StringError>(Message, std::make_error_code(Type));
6
Calling 'make_error<llvm::StringError, const llvm::Twine &, std::error_code>'
50}
51
52static Error checkNumberFits(uint32_t Number, size_t MaxBits,
53 const Twine &FieldName) {
54 assert(1 <= MaxBits && MaxBits <= 32)((1 <= MaxBits && MaxBits <= 32) ? static_cast<
void> (0) : __assert_fail ("1 <= MaxBits && MaxBits <= 32"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 54, __PRETTY_FUNCTION__))
;
55 if (!(Number >> MaxBits))
3
Assuming the condition is false
4
Taking false branch
56 return Error::success();
57 return createError(FieldName + " (" + Twine(Number) + ") does not fit in " +
5
Calling 'createError'
58 Twine(MaxBits) + " bits.",
59 std::errc::value_too_large);
60}
61
62template <typename FitType>
63static Error checkNumberFits(uint32_t Number, const Twine &FieldName) {
64 return checkNumberFits(Number, sizeof(FitType) * 8, FieldName);
2
Calling 'checkNumberFits'
65}
66
67// A similar function for signed integers.
68template <typename FitType>
69static Error checkSignedNumberFits(uint32_t Number, const Twine &FieldName,
70 bool CanBeNegative) {
71 int32_t SignedNum = Number;
72 if (SignedNum < std::numeric_limits<FitType>::min() ||
73 SignedNum > std::numeric_limits<FitType>::max())
74 return createError(FieldName + " (" + Twine(SignedNum) +
75 ") does not fit in " + Twine(sizeof(FitType) * 8) +
76 "-bit signed integer type.",
77 std::errc::value_too_large);
78
79 if (!CanBeNegative && SignedNum < 0)
80 return createError(FieldName + " (" + Twine(SignedNum) +
81 ") cannot be negative.");
82
83 return Error::success();
84}
85
86static Error checkRCInt(RCInt Number, const Twine &FieldName) {
87 if (Number.isLong())
88 return Error::success();
89 return checkNumberFits<uint16_t>(Number, FieldName);
90}
91
92static Error checkIntOrString(IntOrString Value, const Twine &FieldName) {
93 if (!Value.isInt())
94 return Error::success();
95 return checkNumberFits<uint16_t>(Value.getInt(), FieldName);
96}
97
98static bool stripQuotes(StringRef &Str, bool &IsLongString) {
99 if (!Str.contains('"'))
100 return false;
101
102 // Just take the contents of the string, checking if it's been marked long.
103 IsLongString = Str.startswith_lower("L");
104 if (IsLongString)
105 Str = Str.drop_front();
106
107 bool StripSuccess = Str.consume_front("\"") && Str.consume_back("\"");
108 (void)StripSuccess;
109 assert(StripSuccess && "Strings should be enclosed in quotes.")((StripSuccess && "Strings should be enclosed in quotes."
) ? static_cast<void> (0) : __assert_fail ("StripSuccess && \"Strings should be enclosed in quotes.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 109, __PRETTY_FUNCTION__))
;
110 return true;
111}
112
113static UTF16 cp1252ToUnicode(unsigned char C) {
114 static const UTF16 Map80[] = {
115 0x20ac, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
116 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x017d, 0x008f,
117 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
118 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x017e, 0x0178,
119 };
120 if (C >= 0x80 && C <= 0x9F)
121 return Map80[C - 0x80];
122 return C;
123}
124
125// Describes a way to handle '\0' characters when processing the string.
126// rc.exe tool sometimes behaves in a weird way in postprocessing.
127// If the string to be output is equivalent to a C-string (e.g. in MENU
128// titles), string is (predictably) truncated after first 0-byte.
129// When outputting a string table, the behavior is equivalent to appending
130// '\0\0' at the end of the string, and then stripping the string
131// before the first '\0\0' occurrence.
132// Finally, when handling strings in user-defined resources, 0-bytes
133// aren't stripped, nor do they terminate the string.
134
135enum class NullHandlingMethod {
136 UserResource, // Don't terminate string on '\0'.
137 CutAtNull, // Terminate string on '\0'.
138 CutAtDoubleNull // Terminate string on '\0\0'; strip final '\0'.
139};
140
141// Parses an identifier or string and returns a processed version of it:
142// * String the string boundary quotes.
143// * Squash "" to a single ".
144// * Replace the escape sequences with their processed version.
145// For identifiers, this is no-op.
146static Error processString(StringRef Str, NullHandlingMethod NullHandler,
147 bool &IsLongString, SmallVectorImpl<UTF16> &Result,
148 int CodePage) {
149 bool IsString = stripQuotes(Str, IsLongString);
150 SmallVector<UTF16, 128> Chars;
151
152 // Convert the input bytes according to the chosen codepage.
153 if (CodePage == CpUtf8) {
154 convertUTF8ToUTF16String(Str, Chars);
155 } else if (CodePage == CpWin1252) {
156 for (char C : Str)
157 Chars.push_back(cp1252ToUnicode((unsigned char)C));
158 } else {
159 // For other, unknown codepages, only allow plain ASCII input.
160 for (char C : Str) {
161 if ((unsigned char)C > 0x7F)
162 return createError("Non-ASCII 8-bit codepoint (" + Twine(C) +
163 ") can't be interpreted in the current codepage");
164 Chars.push_back((unsigned char)C);
165 }
166 }
167
168 if (!IsString) {
169 // It's an identifier if it's not a string. Make all characters uppercase.
170 for (UTF16 &Ch : Chars) {
171 assert(Ch <= 0x7F && "We didn't allow identifiers to be non-ASCII")((Ch <= 0x7F && "We didn't allow identifiers to be non-ASCII"
) ? static_cast<void> (0) : __assert_fail ("Ch <= 0x7F && \"We didn't allow identifiers to be non-ASCII\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 171, __PRETTY_FUNCTION__))
;
172 Ch = toupper(Ch);
173 }
174 Result.swap(Chars);
175 return Error::success();
176 }
177 Result.reserve(Chars.size());
178 size_t Pos = 0;
179
180 auto AddRes = [&Result, NullHandler, IsLongString](UTF16 Char) -> Error {
181 if (!IsLongString) {
182 if (NullHandler == NullHandlingMethod::UserResource) {
183 // Narrow strings in user-defined resources are *not* output in
184 // UTF-16 format.
185 if (Char > 0xFF)
186 return createError("Non-8-bit codepoint (" + Twine(Char) +
187 ") can't occur in a user-defined narrow string");
188 }
189 }
190
191 Result.push_back(Char);
192 return Error::success();
193 };
194 auto AddEscapedChar = [AddRes, IsLongString, CodePage](UTF16 Char) -> Error {
195 if (!IsLongString) {
196 // Escaped chars in narrow strings have to be interpreted according to
197 // the chosen code page.
198 if (Char > 0xFF)
199 return createError("Non-8-bit escaped char (" + Twine(Char) +
200 ") can't occur in narrow string");
201 if (CodePage == CpUtf8) {
202 if (Char >= 0x80)
203 return createError("Unable to interpret single byte (" + Twine(Char) +
204 ") as UTF-8");
205 } else if (CodePage == CpWin1252) {
206 Char = cp1252ToUnicode(Char);
207 } else {
208 // Unknown/unsupported codepage, only allow ASCII input.
209 if (Char > 0x7F)
210 return createError("Non-ASCII 8-bit codepoint (" + Twine(Char) +
211 ") can't "
212 "occur in a non-Unicode string");
213 }
214 }
215
216 return AddRes(Char);
217 };
218
219 while (Pos < Chars.size()) {
220 UTF16 CurChar = Chars[Pos];
221 ++Pos;
222
223 // Strip double "".
224 if (CurChar == '"') {
225 if (Pos == Chars.size() || Chars[Pos] != '"')
226 return createError("Expected \"\"");
227 ++Pos;
228 RETURN_IF_ERROR(AddRes('"'))if (auto Err = (AddRes('"'))) return Err;;
229 continue;
230 }
231
232 if (CurChar == '\\') {
233 UTF16 TypeChar = Chars[Pos];
234 ++Pos;
235
236 if (TypeChar == 'x' || TypeChar == 'X') {
237 // Read a hex number. Max number of characters to read differs between
238 // narrow and wide strings.
239 UTF16 ReadInt = 0;
240 size_t RemainingChars = IsLongString ? 4 : 2;
241 // We don't want to read non-ASCII hex digits. std:: functions past
242 // 0xFF invoke UB.
243 //
244 // FIXME: actually, Microsoft version probably doesn't check this
245 // condition and uses their Unicode version of 'isxdigit'. However,
246 // there are some hex-digit Unicode character outside of ASCII, and
247 // some of these are actually accepted by rc.exe, the notable example
248 // being fullwidth forms (U+FF10..U+FF19 etc.) These can be written
249 // instead of ASCII digits in \x... escape sequence and get accepted.
250 // However, the resulting hexcodes seem totally unpredictable.
251 // We think it's infeasible to try to reproduce this behavior, nor to
252 // put effort in order to detect it.
253 while (RemainingChars && Pos < Chars.size() && Chars[Pos] < 0x80) {
254 if (!isxdigit(Chars[Pos]))
255 break;
256 char Digit = tolower(Chars[Pos]);
257 ++Pos;
258
259 ReadInt <<= 4;
260 if (isdigit(Digit))
261 ReadInt |= Digit - '0';
262 else
263 ReadInt |= Digit - 'a' + 10;
264
265 --RemainingChars;
266 }
267
268 RETURN_IF_ERROR(AddEscapedChar(ReadInt))if (auto Err = (AddEscapedChar(ReadInt))) return Err;;
269 continue;
270 }
271
272 if (TypeChar >= '0' && TypeChar < '8') {
273 // Read an octal number. Note that we've already read the first digit.
274 UTF16 ReadInt = TypeChar - '0';
275 size_t RemainingChars = IsLongString ? 6 : 2;
276
277 while (RemainingChars && Pos < Chars.size() && Chars[Pos] >= '0' &&
278 Chars[Pos] < '8') {
279 ReadInt <<= 3;
280 ReadInt |= Chars[Pos] - '0';
281 --RemainingChars;
282 ++Pos;
283 }
284
285 RETURN_IF_ERROR(AddEscapedChar(ReadInt))if (auto Err = (AddEscapedChar(ReadInt))) return Err;;
286
287 continue;
288 }
289
290 switch (TypeChar) {
291 case 'A':
292 case 'a':
293 // Windows '\a' translates into '\b' (Backspace).
294 RETURN_IF_ERROR(AddRes('\b'))if (auto Err = (AddRes('\b'))) return Err;;
295 break;
296
297 case 'n': // Somehow, RC doesn't recognize '\N' and '\R'.
298 RETURN_IF_ERROR(AddRes('\n'))if (auto Err = (AddRes('\n'))) return Err;;
299 break;
300
301 case 'r':
302 RETURN_IF_ERROR(AddRes('\r'))if (auto Err = (AddRes('\r'))) return Err;;
303 break;
304
305 case 'T':
306 case 't':
307 RETURN_IF_ERROR(AddRes('\t'))if (auto Err = (AddRes('\t'))) return Err;;
308 break;
309
310 case '\\':
311 RETURN_IF_ERROR(AddRes('\\'))if (auto Err = (AddRes('\\'))) return Err;;
312 break;
313
314 case '"':
315 // RC accepts \" only if another " comes afterwards; then, \"" means
316 // a single ".
317 if (Pos == Chars.size() || Chars[Pos] != '"')
318 return createError("Expected \\\"\"");
319 ++Pos;
320 RETURN_IF_ERROR(AddRes('"'))if (auto Err = (AddRes('"'))) return Err;;
321 break;
322
323 default:
324 // If TypeChar means nothing, \ is should be output to stdout with
325 // following char. However, rc.exe consumes these characters when
326 // dealing with wide strings.
327 if (!IsLongString) {
328 RETURN_IF_ERROR(AddRes('\\'))if (auto Err = (AddRes('\\'))) return Err;;
329 RETURN_IF_ERROR(AddRes(TypeChar))if (auto Err = (AddRes(TypeChar))) return Err;;
330 }
331 break;
332 }
333
334 continue;
335 }
336
337 // If nothing interesting happens, just output the character.
338 RETURN_IF_ERROR(AddRes(CurChar))if (auto Err = (AddRes(CurChar))) return Err;;
339 }
340
341 switch (NullHandler) {
342 case NullHandlingMethod::CutAtNull:
343 for (size_t Pos = 0; Pos < Result.size(); ++Pos)
344 if (Result[Pos] == '\0')
345 Result.resize(Pos);
346 break;
347
348 case NullHandlingMethod::CutAtDoubleNull:
349 for (size_t Pos = 0; Pos + 1 < Result.size(); ++Pos)
350 if (Result[Pos] == '\0' && Result[Pos + 1] == '\0')
351 Result.resize(Pos);
352 if (Result.size() > 0 && Result.back() == '\0')
353 Result.pop_back();
354 break;
355
356 case NullHandlingMethod::UserResource:
357 break;
358 }
359
360 return Error::success();
361}
362
363uint64_t ResourceFileWriter::writeObject(const ArrayRef<uint8_t> Data) {
364 uint64_t Result = tell();
365 FS->write((const char *)Data.begin(), Data.size());
366 return Result;
367}
368
369Error ResourceFileWriter::writeCString(StringRef Str, bool WriteTerminator) {
370 SmallVector<UTF16, 128> ProcessedString;
371 bool IsLongString;
372 RETURN_IF_ERROR(processString(Str, NullHandlingMethod::CutAtNull,if (auto Err = (processString(Str, NullHandlingMethod::CutAtNull
, IsLongString, ProcessedString, Params.CodePage))) return Err
;
373 IsLongString, ProcessedString,if (auto Err = (processString(Str, NullHandlingMethod::CutAtNull
, IsLongString, ProcessedString, Params.CodePage))) return Err
;
374 Params.CodePage))if (auto Err = (processString(Str, NullHandlingMethod::CutAtNull
, IsLongString, ProcessedString, Params.CodePage))) return Err
;
;
375 for (auto Ch : ProcessedString)
376 writeInt<uint16_t>(Ch);
377 if (WriteTerminator)
378 writeInt<uint16_t>(0);
379 return Error::success();
380}
381
382Error ResourceFileWriter::writeIdentifier(const IntOrString &Ident) {
383 return writeIntOrString(Ident);
384}
385
386Error ResourceFileWriter::writeIntOrString(const IntOrString &Value) {
387 if (!Value.isInt())
388 return writeCString(Value.getString());
389
390 writeInt<uint16_t>(0xFFFF);
391 writeInt<uint16_t>(Value.getInt());
392 return Error::success();
393}
394
395void ResourceFileWriter::writeRCInt(RCInt Value) {
396 if (Value.isLong())
397 writeInt<uint32_t>(Value);
398 else
399 writeInt<uint16_t>(Value);
400}
401
402Error ResourceFileWriter::appendFile(StringRef Filename) {
403 bool IsLong;
404 stripQuotes(Filename, IsLong);
405
406 auto File = loadFile(Filename);
407 if (!File)
408 return File.takeError();
409
410 *FS << (*File)->getBuffer();
411 return Error::success();
412}
413
414void ResourceFileWriter::padStream(uint64_t Length) {
415 assert(Length > 0)((Length > 0) ? static_cast<void> (0) : __assert_fail
("Length > 0", "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 415, __PRETTY_FUNCTION__))
;
416 uint64_t Location = tell();
417 Location %= Length;
418 uint64_t Pad = (Length - Location) % Length;
419 for (uint64_t i = 0; i < Pad; ++i)
420 writeInt<uint8_t>(0);
421}
422
423Error ResourceFileWriter::handleError(Error Err, const RCResource *Res) {
424 if (Err)
425 return joinErrors(createError("Error in " + Res->getResourceTypeName() +
426 " statement (ID " + Twine(Res->ResName) +
427 "): "),
428 std::move(Err));
429 return Error::success();
430}
431
432Error ResourceFileWriter::visitNullResource(const RCResource *Res) {
433 return writeResource(Res, &ResourceFileWriter::writeNullBody);
434}
435
436Error ResourceFileWriter::visitAcceleratorsResource(const RCResource *Res) {
437 return writeResource(Res, &ResourceFileWriter::writeAcceleratorsBody);
438}
439
440Error ResourceFileWriter::visitBitmapResource(const RCResource *Res) {
441 return writeResource(Res, &ResourceFileWriter::writeBitmapBody);
442}
443
444Error ResourceFileWriter::visitCursorResource(const RCResource *Res) {
445 return handleError(visitIconOrCursorResource(Res), Res);
446}
447
448Error ResourceFileWriter::visitDialogResource(const RCResource *Res) {
449 return writeResource(Res, &ResourceFileWriter::writeDialogBody);
450}
451
452Error ResourceFileWriter::visitIconResource(const RCResource *Res) {
453 return handleError(visitIconOrCursorResource(Res), Res);
454}
455
456Error ResourceFileWriter::visitCaptionStmt(const CaptionStmt *Stmt) {
457 ObjectData.Caption = Stmt->Value;
458 return Error::success();
459}
460
461Error ResourceFileWriter::visitClassStmt(const ClassStmt *Stmt) {
462 ObjectData.Class = Stmt->Value;
463 return Error::success();
464}
465
466Error ResourceFileWriter::visitHTMLResource(const RCResource *Res) {
467 return writeResource(Res, &ResourceFileWriter::writeHTMLBody);
468}
469
470Error ResourceFileWriter::visitMenuResource(const RCResource *Res) {
471 return writeResource(Res, &ResourceFileWriter::writeMenuBody);
472}
473
474Error ResourceFileWriter::visitStringTableResource(const RCResource *Base) {
475 const auto *Res = cast<StringTableResource>(Base);
476
477 ContextKeeper RAII(this);
478 RETURN_IF_ERROR(Res->applyStmts(this))if (auto Err = (Res->applyStmts(this))) return Err;;
479
480 for (auto &String : Res->Table) {
481 RETURN_IF_ERROR(checkNumberFits<uint16_t>(String.first, "String ID"))if (auto Err = (checkNumberFits<uint16_t>(String.first,
"String ID"))) return Err;
;
482 uint16_t BundleID = String.first >> 4;
483 StringTableInfo::BundleKey Key(BundleID, ObjectData.LanguageInfo);
484 auto &BundleData = StringTableData.BundleData;
485 auto Iter = BundleData.find(Key);
486
487 if (Iter == BundleData.end()) {
488 // Need to create a bundle.
489 StringTableData.BundleList.push_back(Key);
490 auto EmplaceResult = BundleData.emplace(
491 Key, StringTableInfo::Bundle(ObjectData, Res->MemoryFlags));
492 assert(EmplaceResult.second && "Could not create a bundle")((EmplaceResult.second && "Could not create a bundle"
) ? static_cast<void> (0) : __assert_fail ("EmplaceResult.second && \"Could not create a bundle\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 492, __PRETTY_FUNCTION__))
;
493 Iter = EmplaceResult.first;
494 }
495
496 RETURN_IF_ERROR(if (auto Err = (insertStringIntoBundle(Iter->second, String
.first, String.second))) return Err;
497 insertStringIntoBundle(Iter->second, String.first, String.second))if (auto Err = (insertStringIntoBundle(Iter->second, String
.first, String.second))) return Err;
;
498 }
499
500 return Error::success();
501}
502
503Error ResourceFileWriter::visitUserDefinedResource(const RCResource *Res) {
504 return writeResource(Res, &ResourceFileWriter::writeUserDefinedBody);
505}
506
507Error ResourceFileWriter::visitVersionInfoResource(const RCResource *Res) {
508 return writeResource(Res, &ResourceFileWriter::writeVersionInfoBody);
509}
510
511Error ResourceFileWriter::visitCharacteristicsStmt(
512 const CharacteristicsStmt *Stmt) {
513 ObjectData.Characteristics = Stmt->Value;
514 return Error::success();
515}
516
517Error ResourceFileWriter::visitFontStmt(const FontStmt *Stmt) {
518 RETURN_IF_ERROR(checkNumberFits<uint16_t>(Stmt->Size, "Font size"))if (auto Err = (checkNumberFits<uint16_t>(Stmt->Size
, "Font size"))) return Err;
;
519 RETURN_IF_ERROR(checkNumberFits<uint16_t>(Stmt->Weight, "Font weight"))if (auto Err = (checkNumberFits<uint16_t>(Stmt->Weight
, "Font weight"))) return Err;
;
520 RETURN_IF_ERROR(checkNumberFits<uint8_t>(Stmt->Charset, "Font charset"))if (auto Err = (checkNumberFits<uint8_t>(Stmt->Charset
, "Font charset"))) return Err;
;
521 ObjectInfo::FontInfo Font{Stmt->Size, Stmt->Name, Stmt->Weight, Stmt->Italic,
522 Stmt->Charset};
523 ObjectData.Font.emplace(Font);
524 return Error::success();
525}
526
527Error ResourceFileWriter::visitLanguageStmt(const LanguageResource *Stmt) {
528 RETURN_IF_ERROR(checkNumberFits(Stmt->Lang, 10, "Primary language ID"))if (auto Err = (checkNumberFits(Stmt->Lang, 10, "Primary language ID"
))) return Err;
;
529 RETURN_IF_ERROR(checkNumberFits(Stmt->SubLang, 6, "Sublanguage ID"))if (auto Err = (checkNumberFits(Stmt->SubLang, 6, "Sublanguage ID"
))) return Err;
;
530 ObjectData.LanguageInfo = Stmt->Lang | (Stmt->SubLang << 10);
531 return Error::success();
532}
533
534Error ResourceFileWriter::visitStyleStmt(const StyleStmt *Stmt) {
535 ObjectData.Style = Stmt->Value;
536 return Error::success();
537}
538
539Error ResourceFileWriter::visitVersionStmt(const VersionStmt *Stmt) {
540 ObjectData.VersionInfo = Stmt->Value;
541 return Error::success();
542}
543
544Error ResourceFileWriter::writeResource(
545 const RCResource *Res,
546 Error (ResourceFileWriter::*BodyWriter)(const RCResource *)) {
547 // We don't know the sizes yet.
548 object::WinResHeaderPrefix HeaderPrefix{ulittle32_t(0U), ulittle32_t(0U)};
549 uint64_t HeaderLoc = writeObject(HeaderPrefix);
550
551 auto ResType = Res->getResourceType();
552 RETURN_IF_ERROR(checkIntOrString(ResType, "Resource type"))if (auto Err = (checkIntOrString(ResType, "Resource type"))) return
Err;
;
553 RETURN_IF_ERROR(checkIntOrString(Res->ResName, "Resource ID"))if (auto Err = (checkIntOrString(Res->ResName, "Resource ID"
))) return Err;
;
554 RETURN_IF_ERROR(handleError(writeIdentifier(ResType), Res))if (auto Err = (handleError(writeIdentifier(ResType), Res))) return
Err;
;
555 RETURN_IF_ERROR(handleError(writeIdentifier(Res->ResName), Res))if (auto Err = (handleError(writeIdentifier(Res->ResName),
Res))) return Err;
;
556
557 // Apply the resource-local optional statements.
558 ContextKeeper RAII(this);
559 RETURN_IF_ERROR(handleError(Res->applyStmts(this), Res))if (auto Err = (handleError(Res->applyStmts(this), Res))) return
Err;
;
560
561 padStream(sizeof(uint32_t));
562 object::WinResHeaderSuffix HeaderSuffix{
563 ulittle32_t(0), // DataVersion; seems to always be 0
564 ulittle16_t(Res->MemoryFlags), ulittle16_t(ObjectData.LanguageInfo),
565 ulittle32_t(ObjectData.VersionInfo),
566 ulittle32_t(ObjectData.Characteristics)};
567 writeObject(HeaderSuffix);
568
569 uint64_t DataLoc = tell();
570 RETURN_IF_ERROR(handleError((this->*BodyWriter)(Res), Res))if (auto Err = (handleError((this->*BodyWriter)(Res), Res)
)) return Err;
;
571 // RETURN_IF_ERROR(handleError(dumpResource(Ctx)));
572
573 // Update the sizes.
574 HeaderPrefix.DataSize = tell() - DataLoc;
575 HeaderPrefix.HeaderSize = DataLoc - HeaderLoc;
576 writeObjectAt(HeaderPrefix, HeaderLoc);
577 padStream(sizeof(uint32_t));
578
579 return Error::success();
580}
581
582// --- NullResource helpers. --- //
583
584Error ResourceFileWriter::writeNullBody(const RCResource *) {
585 return Error::success();
586}
587
588// --- AcceleratorsResource helpers. --- //
589
590Error ResourceFileWriter::writeSingleAccelerator(
591 const AcceleratorsResource::Accelerator &Obj, bool IsLastItem) {
592 using Accelerator = AcceleratorsResource::Accelerator;
593 using Opt = Accelerator::Options;
594
595 struct AccelTableEntry {
596 ulittle16_t Flags;
597 ulittle16_t ANSICode;
598 ulittle16_t Id;
599 uint16_t Padding;
600 } Entry{ulittle16_t(0), ulittle16_t(0), ulittle16_t(0), 0};
601
602 bool IsASCII = Obj.Flags & Opt::ASCII, IsVirtKey = Obj.Flags & Opt::VIRTKEY;
603
604 // Remove ASCII flags (which doesn't occur in .res files).
605 Entry.Flags = Obj.Flags & ~Opt::ASCII;
606
607 if (IsLastItem)
608 Entry.Flags |= 0x80;
609
610 RETURN_IF_ERROR(checkNumberFits<uint16_t>(Obj.Id, "ACCELERATORS entry ID"))if (auto Err = (checkNumberFits<uint16_t>(Obj.Id, "ACCELERATORS entry ID"
))) return Err;
;
611 Entry.Id = ulittle16_t(Obj.Id);
612
613 auto createAccError = [&Obj](const char *Msg) {
614 return createError("Accelerator ID " + Twine(Obj.Id) + ": " + Msg);
615 };
616
617 if (IsASCII && IsVirtKey)
618 return createAccError("Accelerator can't be both ASCII and VIRTKEY");
619
620 if (!IsVirtKey && (Obj.Flags & (Opt::ALT | Opt::SHIFT | Opt::CONTROL)))
621 return createAccError("Can only apply ALT, SHIFT or CONTROL to VIRTKEY"
622 " accelerators");
623
624 if (Obj.Event.isInt()) {
625 if (!IsASCII && !IsVirtKey)
626 return createAccError(
627 "Accelerator with a numeric event must be either ASCII"
628 " or VIRTKEY");
629
630 uint32_t EventVal = Obj.Event.getInt();
631 RETURN_IF_ERROR(if (auto Err = (checkNumberFits<uint16_t>(EventVal, "Numeric event key ID"
))) return Err;
632 checkNumberFits<uint16_t>(EventVal, "Numeric event key ID"))if (auto Err = (checkNumberFits<uint16_t>(EventVal, "Numeric event key ID"
))) return Err;
;
633 Entry.ANSICode = ulittle16_t(EventVal);
634 writeObject(Entry);
635 return Error::success();
636 }
637
638 StringRef Str = Obj.Event.getString();
639 bool IsWide;
640 stripQuotes(Str, IsWide);
641
642 if (Str.size() == 0 || Str.size() > 2)
643 return createAccError(
644 "Accelerator string events should have length 1 or 2");
645
646 if (Str[0] == '^') {
647 if (Str.size() == 1)
648 return createAccError("No character following '^' in accelerator event");
649 if (IsVirtKey)
650 return createAccError(
651 "VIRTKEY accelerator events can't be preceded by '^'");
652
653 char Ch = Str[1];
654 if (Ch >= 'a' && Ch <= 'z')
655 Entry.ANSICode = ulittle16_t(Ch - 'a' + 1);
656 else if (Ch >= 'A' && Ch <= 'Z')
657 Entry.ANSICode = ulittle16_t(Ch - 'A' + 1);
658 else
659 return createAccError("Control character accelerator event should be"
660 " alphabetic");
661
662 writeObject(Entry);
663 return Error::success();
664 }
665
666 if (Str.size() == 2)
667 return createAccError("Event string should be one-character, possibly"
668 " preceded by '^'");
669
670 uint8_t EventCh = Str[0];
671 // The original tool just warns in this situation. We chose to fail.
672 if (IsVirtKey && !isalnum(EventCh))
673 return createAccError("Non-alphanumeric characters cannot describe virtual"
674 " keys");
675 if (EventCh > 0x7F)
676 return createAccError("Non-ASCII description of accelerator");
677
678 if (IsVirtKey)
679 EventCh = toupper(EventCh);
680 Entry.ANSICode = ulittle16_t(EventCh);
681 writeObject(Entry);
682 return Error::success();
683}
684
685Error ResourceFileWriter::writeAcceleratorsBody(const RCResource *Base) {
686 auto *Res = cast<AcceleratorsResource>(Base);
687 size_t AcceleratorId = 0;
688 for (auto &Acc : Res->Accelerators) {
689 ++AcceleratorId;
690 RETURN_IF_ERROR(if (auto Err = (writeSingleAccelerator(Acc, AcceleratorId == Res
->Accelerators.size()))) return Err;
691 writeSingleAccelerator(Acc, AcceleratorId == Res->Accelerators.size()))if (auto Err = (writeSingleAccelerator(Acc, AcceleratorId == Res
->Accelerators.size()))) return Err;
;
692 }
693 return Error::success();
694}
695
696// --- BitmapResource helpers. --- //
697
698Error ResourceFileWriter::writeBitmapBody(const RCResource *Base) {
699 StringRef Filename = cast<BitmapResource>(Base)->BitmapLoc;
700 bool IsLong;
701 stripQuotes(Filename, IsLong);
702
703 auto File = loadFile(Filename);
704 if (!File)
705 return File.takeError();
706
707 StringRef Buffer = (*File)->getBuffer();
708
709 // Skip the 14 byte BITMAPFILEHEADER.
710 constexpr size_t BITMAPFILEHEADER_size = 14;
711 if (Buffer.size() < BITMAPFILEHEADER_size || Buffer[0] != 'B' ||
712 Buffer[1] != 'M')
713 return createError("Incorrect bitmap file.");
714
715 *FS << Buffer.substr(BITMAPFILEHEADER_size);
716 return Error::success();
717}
718
719// --- CursorResource and IconResource helpers. --- //
720
721// ICONRESDIR structure. Describes a single icon in resouce group.
722//
723// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648016.aspx
724struct IconResDir {
725 uint8_t Width;
726 uint8_t Height;
727 uint8_t ColorCount;
728 uint8_t Reserved;
729};
730
731// CURSORDIR structure. Describes a single cursor in resource group.
732//
733// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648011(v=vs.85).aspx
734struct CursorDir {
735 ulittle16_t Width;
736 ulittle16_t Height;
737};
738
739// RESDIRENTRY structure, stripped from the last item. Stripping made
740// for compatibility with RESDIR.
741//
742// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648026(v=vs.85).aspx
743struct ResourceDirEntryStart {
744 union {
745 CursorDir Cursor; // Used in CURSOR resources.
746 IconResDir Icon; // Used in .ico and .cur files, and ICON resources.
747 };
748 ulittle16_t Planes; // HotspotX (.cur files but not CURSOR resource).
749 ulittle16_t BitCount; // HotspotY (.cur files but not CURSOR resource).
750 ulittle32_t Size;
751 // ulittle32_t ImageOffset; // Offset to image data (ICONDIRENTRY only).
752 // ulittle16_t IconID; // Resource icon ID (RESDIR only).
753};
754
755// BITMAPINFOHEADER structure. Describes basic information about the bitmap
756// being read.
757//
758// Ref: msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx
759struct BitmapInfoHeader {
760 ulittle32_t Size;
761 ulittle32_t Width;
762 ulittle32_t Height;
763 ulittle16_t Planes;
764 ulittle16_t BitCount;
765 ulittle32_t Compression;
766 ulittle32_t SizeImage;
767 ulittle32_t XPelsPerMeter;
768 ulittle32_t YPelsPerMeter;
769 ulittle32_t ClrUsed;
770 ulittle32_t ClrImportant;
771};
772
773// Group icon directory header. Called ICONDIR in .ico/.cur files and
774// NEWHEADER in .res files.
775//
776// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648023(v=vs.85).aspx
777struct GroupIconDir {
778 ulittle16_t Reserved; // Always 0.
779 ulittle16_t ResType; // 1 for icons, 2 for cursors.
780 ulittle16_t ResCount; // Number of items.
781};
782
783enum class IconCursorGroupType { Icon, Cursor };
784
785class SingleIconCursorResource : public RCResource {
786public:
787 IconCursorGroupType Type;
788 const ResourceDirEntryStart &Header;
789 ArrayRef<uint8_t> Image;
790
791 SingleIconCursorResource(IconCursorGroupType ResourceType,
792 const ResourceDirEntryStart &HeaderEntry,
793 ArrayRef<uint8_t> ImageData, uint16_t Flags)
794 : RCResource(Flags), Type(ResourceType), Header(HeaderEntry),
795 Image(ImageData) {}
796
797 Twine getResourceTypeName() const override { return "Icon/cursor image"; }
798 IntOrString getResourceType() const override {
799 return Type == IconCursorGroupType::Icon ? RkSingleIcon : RkSingleCursor;
800 }
801 ResourceKind getKind() const override { return RkSingleCursorOrIconRes; }
802 static bool classof(const RCResource *Res) {
803 return Res->getKind() == RkSingleCursorOrIconRes;
804 }
805};
806
807class IconCursorGroupResource : public RCResource {
808public:
809 IconCursorGroupType Type;
810 GroupIconDir Header;
811 std::vector<ResourceDirEntryStart> ItemEntries;
812
813 IconCursorGroupResource(IconCursorGroupType ResourceType,
814 const GroupIconDir &HeaderData,
815 std::vector<ResourceDirEntryStart> &&Entries)
816 : Type(ResourceType), Header(HeaderData),
817 ItemEntries(std::move(Entries)) {}
818
819 Twine getResourceTypeName() const override { return "Icon/cursor group"; }
820 IntOrString getResourceType() const override {
821 return Type == IconCursorGroupType::Icon ? RkIconGroup : RkCursorGroup;
822 }
823 ResourceKind getKind() const override { return RkCursorOrIconGroupRes; }
824 static bool classof(const RCResource *Res) {
825 return Res->getKind() == RkCursorOrIconGroupRes;
826 }
827};
828
829Error ResourceFileWriter::writeSingleIconOrCursorBody(const RCResource *Base) {
830 auto *Res = cast<SingleIconCursorResource>(Base);
831 if (Res->Type == IconCursorGroupType::Cursor) {
832 // In case of cursors, two WORDS are appended to the beginning
833 // of the resource: HotspotX (Planes in RESDIRENTRY),
834 // and HotspotY (BitCount).
835 //
836 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648026.aspx
837 // (Remarks section).
838 writeObject(Res->Header.Planes);
839 writeObject(Res->Header.BitCount);
840 }
841
842 writeObject(Res->Image);
843 return Error::success();
844}
845
846Error ResourceFileWriter::writeIconOrCursorGroupBody(const RCResource *Base) {
847 auto *Res = cast<IconCursorGroupResource>(Base);
848 writeObject(Res->Header);
849 for (auto Item : Res->ItemEntries) {
850 writeObject(Item);
851 writeInt(IconCursorID++);
852 }
853 return Error::success();
854}
855
856Error ResourceFileWriter::visitSingleIconOrCursor(const RCResource *Res) {
857 return writeResource(Res, &ResourceFileWriter::writeSingleIconOrCursorBody);
858}
859
860Error ResourceFileWriter::visitIconOrCursorGroup(const RCResource *Res) {
861 return writeResource(Res, &ResourceFileWriter::writeIconOrCursorGroupBody);
862}
863
864Error ResourceFileWriter::visitIconOrCursorResource(const RCResource *Base) {
865 IconCursorGroupType Type;
866 StringRef FileStr;
867 IntOrString ResName = Base->ResName;
868
869 if (auto *IconRes = dyn_cast<IconResource>(Base)) {
870 FileStr = IconRes->IconLoc;
871 Type = IconCursorGroupType::Icon;
872 } else {
873 auto *CursorRes = dyn_cast<CursorResource>(Base);
874 FileStr = CursorRes->CursorLoc;
875 Type = IconCursorGroupType::Cursor;
876 }
877
878 bool IsLong;
879 stripQuotes(FileStr, IsLong);
880 auto File = loadFile(FileStr);
881
882 if (!File)
883 return File.takeError();
884
885 BinaryStreamReader Reader((*File)->getBuffer(), support::little);
886
887 // Read the file headers.
888 // - At the beginning, ICONDIR/NEWHEADER header.
889 // - Then, a number of RESDIR headers follow. These contain offsets
890 // to data.
891 const GroupIconDir *Header;
892
893 RETURN_IF_ERROR(Reader.readObject(Header))if (auto Err = (Reader.readObject(Header))) return Err;;
894 if (Header->Reserved != 0)
895 return createError("Incorrect icon/cursor Reserved field; should be 0.");
896 uint16_t NeededType = Type == IconCursorGroupType::Icon ? 1 : 2;
897 if (Header->ResType != NeededType)
898 return createError("Incorrect icon/cursor ResType field; should be " +
899 Twine(NeededType) + ".");
900
901 uint16_t NumItems = Header->ResCount;
902
903 // Read single ico/cur headers.
904 std::vector<ResourceDirEntryStart> ItemEntries;
905 ItemEntries.reserve(NumItems);
906 std::vector<uint32_t> ItemOffsets(NumItems);
907 for (size_t ID = 0; ID < NumItems; ++ID) {
908 const ResourceDirEntryStart *Object;
909 RETURN_IF_ERROR(Reader.readObject(Object))if (auto Err = (Reader.readObject(Object))) return Err;;
910 ItemEntries.push_back(*Object);
911 RETURN_IF_ERROR(Reader.readInteger(ItemOffsets[ID]))if (auto Err = (Reader.readInteger(ItemOffsets[ID]))) return Err
;
;
912 }
913
914 // Now write each icon/cursors one by one. At first, all the contents
915 // without ICO/CUR header. This is described by SingleIconCursorResource.
916 for (size_t ID = 0; ID < NumItems; ++ID) {
917 // Load the fragment of file.
918 Reader.setOffset(ItemOffsets[ID]);
919 ArrayRef<uint8_t> Image;
920 RETURN_IF_ERROR(Reader.readArray(Image, ItemEntries[ID].Size))if (auto Err = (Reader.readArray(Image, ItemEntries[ID].Size)
)) return Err;
;
921 SingleIconCursorResource SingleRes(Type, ItemEntries[ID], Image,
922 Base->MemoryFlags);
923 SingleRes.setName(IconCursorID + ID);
924 RETURN_IF_ERROR(visitSingleIconOrCursor(&SingleRes))if (auto Err = (visitSingleIconOrCursor(&SingleRes))) return
Err;
;
925 }
926
927 // Now, write all the headers concatenated into a separate resource.
928 for (size_t ID = 0; ID < NumItems; ++ID) {
929 // We need to rewrite the cursor headers, and fetch actual values
930 // for Planes/BitCount.
931 const auto &OldHeader = ItemEntries[ID];
932 ResourceDirEntryStart NewHeader = OldHeader;
933
934 if (Type == IconCursorGroupType::Cursor) {
935 NewHeader.Cursor.Width = OldHeader.Icon.Width;
936 // Each cursor in fact stores two bitmaps, one under another.
937 // Height provided in cursor definition describes the height of the
938 // cursor, whereas the value existing in resource definition describes
939 // the height of the bitmap. Therefore, we need to double this height.
940 NewHeader.Cursor.Height = OldHeader.Icon.Height * 2;
941
942 // Two WORDs were written at the beginning of the resource (hotspot
943 // location). This is reflected in Size field.
944 NewHeader.Size += 2 * sizeof(uint16_t);
945 }
946
947 // Now, we actually need to read the bitmap header to find
948 // the number of planes and the number of bits per pixel.
949 Reader.setOffset(ItemOffsets[ID]);
950 const BitmapInfoHeader *BMPHeader;
951 RETURN_IF_ERROR(Reader.readObject(BMPHeader))if (auto Err = (Reader.readObject(BMPHeader))) return Err;;
952 if (BMPHeader->Size == sizeof(BitmapInfoHeader)) {
953 NewHeader.Planes = BMPHeader->Planes;
954 NewHeader.BitCount = BMPHeader->BitCount;
955 } else {
956 // A PNG .ico file.
957 // https://blogs.msdn.microsoft.com/oldnewthing/20101022-00/?p=12473
958 // "The image must be in 32bpp"
959 NewHeader.Planes = 1;
960 NewHeader.BitCount = 32;
961 }
962
963 ItemEntries[ID] = NewHeader;
964 }
965
966 IconCursorGroupResource HeaderRes(Type, *Header, std::move(ItemEntries));
967 HeaderRes.setName(ResName);
968 if (Base->MemoryFlags & MfPreload) {
969 HeaderRes.MemoryFlags |= MfPreload;
970 HeaderRes.MemoryFlags &= ~MfPure;
971 }
972 RETURN_IF_ERROR(visitIconOrCursorGroup(&HeaderRes))if (auto Err = (visitIconOrCursorGroup(&HeaderRes))) return
Err;
;
973
974 return Error::success();
975}
976
977// --- DialogResource helpers. --- //
978
979Error ResourceFileWriter::writeSingleDialogControl(const Control &Ctl,
980 bool IsExtended) {
981 // Each control should be aligned to DWORD.
982 padStream(sizeof(uint32_t));
983
984 auto TypeInfo = Control::SupportedCtls.lookup(Ctl.Type);
985 uint32_t CtlStyle = TypeInfo.Style | Ctl.Style.getValueOr(0);
986 uint32_t CtlExtStyle = Ctl.ExtStyle.getValueOr(0);
987
988 // DIALOG(EX) item header prefix.
989 if (!IsExtended) {
990 struct {
991 ulittle32_t Style;
992 ulittle32_t ExtStyle;
993 } Prefix{ulittle32_t(CtlStyle), ulittle32_t(CtlExtStyle)};
994 writeObject(Prefix);
995 } else {
996 struct {
997 ulittle32_t HelpID;
998 ulittle32_t ExtStyle;
999 ulittle32_t Style;
1000 } Prefix{ulittle32_t(Ctl.HelpID.getValueOr(0)), ulittle32_t(CtlExtStyle),
1001 ulittle32_t(CtlStyle)};
1002 writeObject(Prefix);
1003 }
1004
1005 // Common fixed-length part.
1006 RETURN_IF_ERROR(checkSignedNumberFits<int16_t>(if (auto Err = (checkSignedNumberFits<int16_t>( Ctl.X, "Dialog control x-coordinate"
, true))) return Err;
1007 Ctl.X, "Dialog control x-coordinate", true))if (auto Err = (checkSignedNumberFits<int16_t>( Ctl.X, "Dialog control x-coordinate"
, true))) return Err;
;
1008 RETURN_IF_ERROR(checkSignedNumberFits<int16_t>(if (auto Err = (checkSignedNumberFits<int16_t>( Ctl.Y, "Dialog control y-coordinate"
, true))) return Err;
1009 Ctl.Y, "Dialog control y-coordinate", true))if (auto Err = (checkSignedNumberFits<int16_t>( Ctl.Y, "Dialog control y-coordinate"
, true))) return Err;
;
1010 RETURN_IF_ERROR(if (auto Err = (checkSignedNumberFits<int16_t>(Ctl.Width
, "Dialog control width", false))) return Err;
1011 checkSignedNumberFits<int16_t>(Ctl.Width, "Dialog control width", false))if (auto Err = (checkSignedNumberFits<int16_t>(Ctl.Width
, "Dialog control width", false))) return Err;
;
1012 RETURN_IF_ERROR(checkSignedNumberFits<int16_t>(if (auto Err = (checkSignedNumberFits<int16_t>( Ctl.Height
, "Dialog control height", false))) return Err;
1013 Ctl.Height, "Dialog control height", false))if (auto Err = (checkSignedNumberFits<int16_t>( Ctl.Height
, "Dialog control height", false))) return Err;
;
1014 struct {
1015 ulittle16_t X;
1016 ulittle16_t Y;
1017 ulittle16_t Width;
1018 ulittle16_t Height;
1019 } Middle{ulittle16_t(Ctl.X), ulittle16_t(Ctl.Y), ulittle16_t(Ctl.Width),
1020 ulittle16_t(Ctl.Height)};
1021 writeObject(Middle);
1022
1023 // ID; it's 16-bit in DIALOG and 32-bit in DIALOGEX.
1024 if (!IsExtended) {
1025 // It's common to use -1, i.e. UINT32_MAX, for controls one doesn't
1026 // want to refer to later.
1027 if (Ctl.ID != static_cast<uint32_t>(-1))
1028 RETURN_IF_ERROR(checkNumberFits<uint16_t>(if (auto Err = (checkNumberFits<uint16_t>( Ctl.ID, "Control ID in simple DIALOG resource"
))) return Err;
1029 Ctl.ID, "Control ID in simple DIALOG resource"))if (auto Err = (checkNumberFits<uint16_t>( Ctl.ID, "Control ID in simple DIALOG resource"
))) return Err;
;
1030 writeInt<uint16_t>(Ctl.ID);
1031 } else {
1032 writeInt<uint32_t>(Ctl.ID);
1033 }
1034
1035 // Window class - either 0xFFFF + 16-bit integer or a string.
1036 RETURN_IF_ERROR(writeIntOrString(Ctl.Class))if (auto Err = (writeIntOrString(Ctl.Class))) return Err;;
1037
1038 // Element caption/reference ID. ID is preceded by 0xFFFF.
1039 RETURN_IF_ERROR(checkIntOrString(Ctl.Title, "Control reference ID"))if (auto Err = (checkIntOrString(Ctl.Title, "Control reference ID"
))) return Err;
;
1040 RETURN_IF_ERROR(writeIntOrString(Ctl.Title))if (auto Err = (writeIntOrString(Ctl.Title))) return Err;;
1041
1042 // # bytes of extra creation data count. Don't pass any.
1043 writeInt<uint16_t>(0);
1044
1045 return Error::success();
1046}
1047
1048Error ResourceFileWriter::writeDialogBody(const RCResource *Base) {
1049 auto *Res = cast<DialogResource>(Base);
1050
1051 // Default style: WS_POPUP | WS_BORDER | WS_SYSMENU.
1052 const uint32_t DefaultStyle = 0x80880000;
1053 const uint32_t StyleFontFlag = 0x40;
1054 const uint32_t StyleCaptionFlag = 0x00C00000;
1055
1056 uint32_t UsedStyle = ObjectData.Style.getValueOr(DefaultStyle);
1057 if (ObjectData.Font)
1058 UsedStyle |= StyleFontFlag;
1059 else
1060 UsedStyle &= ~StyleFontFlag;
1061
1062 // Actually, in case of empty (but existent) caption, the examined field
1063 // is equal to "\"\"". That's why empty captions are still noticed.
1064 if (ObjectData.Caption != "")
1065 UsedStyle |= StyleCaptionFlag;
1066
1067 const uint16_t DialogExMagic = 0xFFFF;
1068
1069 // Write DIALOG(EX) header prefix. These are pretty different.
1070 if (!Res->IsExtended) {
1071 // We cannot let the higher word of DefaultStyle be equal to 0xFFFF.
1072 // In such a case, whole object (in .res file) is equivalent to a
1073 // DIALOGEX. It might lead to access violation/segmentation fault in
1074 // resource readers. For example,
1075 // 1 DIALOG 0, 0, 0, 65432
1076 // STYLE 0xFFFF0001 {}
1077 // would be compiled to a DIALOGEX with 65432 controls.
1078 if ((UsedStyle >> 16) == DialogExMagic)
1079 return createError("16 higher bits of DIALOG resource style cannot be"
1080 " equal to 0xFFFF");
1081
1082 struct {
1083 ulittle32_t Style;
1084 ulittle32_t ExtStyle;
1085 } Prefix{ulittle32_t(UsedStyle),
1086 ulittle32_t(0)}; // As of now, we don't keep EXSTYLE.
1087
1088 writeObject(Prefix);
1089 } else {
1090 struct {
1091 ulittle16_t Version;
1092 ulittle16_t Magic;
1093 ulittle32_t HelpID;
1094 ulittle32_t ExtStyle;
1095 ulittle32_t Style;
1096 } Prefix{ulittle16_t(1), ulittle16_t(DialogExMagic),
1097 ulittle32_t(Res->HelpID), ulittle32_t(0), ulittle32_t(UsedStyle)};
1098
1099 writeObject(Prefix);
1100 }
1101
1102 // Now, a common part. First, fixed-length fields.
1103 RETURN_IF_ERROR(checkNumberFits<uint16_t>(Res->Controls.size(),if (auto Err = (checkNumberFits<uint16_t>(Res->Controls
.size(), "Number of dialog controls"))) return Err;
1104 "Number of dialog controls"))if (auto Err = (checkNumberFits<uint16_t>(Res->Controls
.size(), "Number of dialog controls"))) return Err;
;
1105 RETURN_IF_ERROR(if (auto Err = (checkSignedNumberFits<int16_t>(Res->
X, "Dialog x-coordinate", true))) return Err;
1106 checkSignedNumberFits<int16_t>(Res->X, "Dialog x-coordinate", true))if (auto Err = (checkSignedNumberFits<int16_t>(Res->
X, "Dialog x-coordinate", true))) return Err;
;
1107 RETURN_IF_ERROR(if (auto Err = (checkSignedNumberFits<int16_t>(Res->
Y, "Dialog y-coordinate", true))) return Err;
1108 checkSignedNumberFits<int16_t>(Res->Y, "Dialog y-coordinate", true))if (auto Err = (checkSignedNumberFits<int16_t>(Res->
Y, "Dialog y-coordinate", true))) return Err;
;
1109 RETURN_IF_ERROR(if (auto Err = (checkSignedNumberFits<int16_t>(Res->
Width, "Dialog width", false))) return Err;
1110 checkSignedNumberFits<int16_t>(Res->Width, "Dialog width", false))if (auto Err = (checkSignedNumberFits<int16_t>(Res->
Width, "Dialog width", false))) return Err;
;
1111 RETURN_IF_ERROR(if (auto Err = (checkSignedNumberFits<int16_t>(Res->
Height, "Dialog height", false))) return Err;
1112 checkSignedNumberFits<int16_t>(Res->Height, "Dialog height", false))if (auto Err = (checkSignedNumberFits<int16_t>(Res->
Height, "Dialog height", false))) return Err;
;
1113 struct {
1114 ulittle16_t Count;
1115 ulittle16_t PosX;
1116 ulittle16_t PosY;
1117 ulittle16_t DialogWidth;
1118 ulittle16_t DialogHeight;
1119 } Middle{ulittle16_t(Res->Controls.size()), ulittle16_t(Res->X),
1120 ulittle16_t(Res->Y), ulittle16_t(Res->Width),
1121 ulittle16_t(Res->Height)};
1122 writeObject(Middle);
1123
1124 // MENU field. As of now, we don't keep them in the state and can peacefully
1125 // think there is no menu attached to the dialog.
1126 writeInt<uint16_t>(0);
1127
1128 // Window CLASS field.
1129 RETURN_IF_ERROR(writeIntOrString(ObjectData.Class))if (auto Err = (writeIntOrString(ObjectData.Class))) return Err
;
;
1130
1131 // Window title or a single word equal to 0.
1132 RETURN_IF_ERROR(writeCString(ObjectData.Caption))if (auto Err = (writeCString(ObjectData.Caption))) return Err
;
;
1133
1134 // If there *is* a window font declared, output its data.
1135 auto &Font = ObjectData.Font;
1136 if (Font) {
1137 writeInt<uint16_t>(Font->Size);
1138 // Additional description occurs only in DIALOGEX.
1139 if (Res->IsExtended) {
1140 writeInt<uint16_t>(Font->Weight);
1141 writeInt<uint8_t>(Font->IsItalic);
1142 writeInt<uint8_t>(Font->Charset);
1143 }
1144 RETURN_IF_ERROR(writeCString(Font->Typeface))if (auto Err = (writeCString(Font->Typeface))) return Err;;
1145 }
1146
1147 auto handleCtlError = [&](Error &&Err, const Control &Ctl) -> Error {
1148 if (!Err)
1149 return Error::success();
1150 return joinErrors(createError("Error in " + Twine(Ctl.Type) +
1151 " control (ID " + Twine(Ctl.ID) + "):"),
1152 std::move(Err));
1153 };
1154
1155 for (auto &Ctl : Res->Controls)
1156 RETURN_IF_ERROR(if (auto Err = (handleCtlError(writeSingleDialogControl(Ctl, Res
->IsExtended), Ctl))) return Err;
1157 handleCtlError(writeSingleDialogControl(Ctl, Res->IsExtended), Ctl))if (auto Err = (handleCtlError(writeSingleDialogControl(Ctl, Res
->IsExtended), Ctl))) return Err;
;
1158
1159 return Error::success();
1160}
1161
1162// --- HTMLResource helpers. --- //
1163
1164Error ResourceFileWriter::writeHTMLBody(const RCResource *Base) {
1165 return appendFile(cast<HTMLResource>(Base)->HTMLLoc);
1166}
1167
1168// --- MenuResource helpers. --- //
1169
1170Error ResourceFileWriter::writeMenuDefinition(
1171 const std::unique_ptr<MenuDefinition> &Def, uint16_t Flags) {
1172 assert(Def)((Def) ? static_cast<void> (0) : __assert_fail ("Def", "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 1172, __PRETTY_FUNCTION__))
;
1173 const MenuDefinition *DefPtr = Def.get();
1174
1175 if (auto *MenuItemPtr = dyn_cast<MenuItem>(DefPtr)) {
1176 writeInt<uint16_t>(Flags);
1177 RETURN_IF_ERROR(if (auto Err = (checkNumberFits<uint16_t>(MenuItemPtr->
Id, "MENUITEM action ID"))) return Err;
1178 checkNumberFits<uint16_t>(MenuItemPtr->Id, "MENUITEM action ID"))if (auto Err = (checkNumberFits<uint16_t>(MenuItemPtr->
Id, "MENUITEM action ID"))) return Err;
;
1179 writeInt<uint16_t>(MenuItemPtr->Id);
1180 RETURN_IF_ERROR(writeCString(MenuItemPtr->Name))if (auto Err = (writeCString(MenuItemPtr->Name))) return Err
;
;
1181 return Error::success();
1182 }
1183
1184 if (isa<MenuSeparator>(DefPtr)) {
1185 writeInt<uint16_t>(Flags);
1186 writeInt<uint32_t>(0);
1187 return Error::success();
1188 }
1189
1190 auto *PopupPtr = cast<PopupItem>(DefPtr);
1191 writeInt<uint16_t>(Flags);
1192 RETURN_IF_ERROR(writeCString(PopupPtr->Name))if (auto Err = (writeCString(PopupPtr->Name))) return Err;;
1193 return writeMenuDefinitionList(PopupPtr->SubItems);
1194}
1195
1196Error ResourceFileWriter::writeMenuDefinitionList(
1197 const MenuDefinitionList &List) {
1198 for (auto &Def : List.Definitions) {
1199 uint16_t Flags = Def->getResFlags();
1200 // Last element receives an additional 0x80 flag.
1201 const uint16_t LastElementFlag = 0x0080;
1202 if (&Def == &List.Definitions.back())
1203 Flags |= LastElementFlag;
1204
1205 RETURN_IF_ERROR(writeMenuDefinition(Def, Flags))if (auto Err = (writeMenuDefinition(Def, Flags))) return Err;;
1206 }
1207 return Error::success();
1208}
1209
1210Error ResourceFileWriter::writeMenuBody(const RCResource *Base) {
1211 // At first, MENUHEADER structure. In fact, these are two WORDs equal to 0.
1212 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648018.aspx
1213 writeInt<uint32_t>(0);
1214
1215 return writeMenuDefinitionList(cast<MenuResource>(Base)->Elements);
1216}
1217
1218// --- StringTableResource helpers. --- //
1219
1220class BundleResource : public RCResource {
1221public:
1222 using BundleType = ResourceFileWriter::StringTableInfo::Bundle;
1223 BundleType Bundle;
1224
1225 BundleResource(const BundleType &StrBundle)
1226 : RCResource(StrBundle.MemoryFlags), Bundle(StrBundle) {}
1227 IntOrString getResourceType() const override { return 6; }
1228
1229 ResourceKind getKind() const override { return RkStringTableBundle; }
1230 static bool classof(const RCResource *Res) {
1231 return Res->getKind() == RkStringTableBundle;
1232 }
1233 Twine getResourceTypeName() const override { return "STRINGTABLE"; }
1234};
1235
1236Error ResourceFileWriter::visitStringTableBundle(const RCResource *Res) {
1237 return writeResource(Res, &ResourceFileWriter::writeStringTableBundleBody);
1238}
1239
1240Error ResourceFileWriter::insertStringIntoBundle(
1241 StringTableInfo::Bundle &Bundle, uint16_t StringID, StringRef String) {
1242 uint16_t StringLoc = StringID & 15;
1243 if (Bundle.Data[StringLoc])
1244 return createError("Multiple STRINGTABLE strings located under ID " +
1245 Twine(StringID));
1246 Bundle.Data[StringLoc] = String;
1247 return Error::success();
1248}
1249
1250Error ResourceFileWriter::writeStringTableBundleBody(const RCResource *Base) {
1251 auto *Res = cast<BundleResource>(Base);
1252 for (size_t ID = 0; ID < Res->Bundle.Data.size(); ++ID) {
1253 // The string format is a tiny bit different here. We
1254 // first output the size of the string, and then the string itself
1255 // (which is not null-terminated).
1256 bool IsLongString;
1257 SmallVector<UTF16, 128> Data;
1258 RETURN_IF_ERROR(processString(Res->Bundle.Data[ID].getValueOr(StringRef()),if (auto Err = (processString(Res->Bundle.Data[ID].getValueOr
(StringRef()), NullHandlingMethod::CutAtDoubleNull, IsLongString
, Data, Params.CodePage))) return Err;
1259 NullHandlingMethod::CutAtDoubleNull,if (auto Err = (processString(Res->Bundle.Data[ID].getValueOr
(StringRef()), NullHandlingMethod::CutAtDoubleNull, IsLongString
, Data, Params.CodePage))) return Err;
1260 IsLongString, Data, Params.CodePage))if (auto Err = (processString(Res->Bundle.Data[ID].getValueOr
(StringRef()), NullHandlingMethod::CutAtDoubleNull, IsLongString
, Data, Params.CodePage))) return Err;
;
1261 if (AppendNull && Res->Bundle.Data[ID])
1262 Data.push_back('\0');
1263 RETURN_IF_ERROR(if (auto Err = (checkNumberFits<uint16_t>(Data.size(), "STRINGTABLE string size"
))) return Err;
1264 checkNumberFits<uint16_t>(Data.size(), "STRINGTABLE string size"))if (auto Err = (checkNumberFits<uint16_t>(Data.size(), "STRINGTABLE string size"
))) return Err;
;
1265 writeInt<uint16_t>(Data.size());
1266 for (auto Char : Data)
1267 writeInt(Char);
1268 }
1269 return Error::success();
1270}
1271
1272Error ResourceFileWriter::dumpAllStringTables() {
1273 for (auto Key : StringTableData.BundleList) {
1274 auto Iter = StringTableData.BundleData.find(Key);
1275 assert(Iter != StringTableData.BundleData.end())((Iter != StringTableData.BundleData.end()) ? static_cast<
void> (0) : __assert_fail ("Iter != StringTableData.BundleData.end()"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 1275, __PRETTY_FUNCTION__))
;
1276
1277 // For a moment, revert the context info to moment of bundle declaration.
1278 ContextKeeper RAII(this);
1279 ObjectData = Iter->second.DeclTimeInfo;
1280
1281 BundleResource Res(Iter->second);
1282 // Bundle #(k+1) contains keys [16k, 16k + 15].
1283 Res.setName(Key.first + 1);
1284 RETURN_IF_ERROR(visitStringTableBundle(&Res))if (auto Err = (visitStringTableBundle(&Res))) return Err
;
;
1285 }
1286 return Error::success();
1287}
1288
1289// --- UserDefinedResource helpers. --- //
1290
1291Error ResourceFileWriter::writeUserDefinedBody(const RCResource *Base) {
1292 auto *Res = cast<UserDefinedResource>(Base);
1293
1294 if (Res->IsFileResource)
1295 return appendFile(Res->FileLoc);
1296
1297 for (auto &Elem : Res->Contents) {
1298 if (Elem.isInt()) {
1299 RETURN_IF_ERROR(if (auto Err = (checkRCInt(Elem.getInt(), "Number in user-defined resource"
))) return Err;
1300 checkRCInt(Elem.getInt(), "Number in user-defined resource"))if (auto Err = (checkRCInt(Elem.getInt(), "Number in user-defined resource"
))) return Err;
;
1301 writeRCInt(Elem.getInt());
1302 continue;
1303 }
1304
1305 SmallVector<UTF16, 128> ProcessedString;
1306 bool IsLongString;
1307 RETURN_IF_ERROR(if (auto Err = (processString(Elem.getString(), NullHandlingMethod
::UserResource, IsLongString, ProcessedString, Params.CodePage
))) return Err;
1308 processString(Elem.getString(), NullHandlingMethod::UserResource,if (auto Err = (processString(Elem.getString(), NullHandlingMethod
::UserResource, IsLongString, ProcessedString, Params.CodePage
))) return Err;
1309 IsLongString, ProcessedString, Params.CodePage))if (auto Err = (processString(Elem.getString(), NullHandlingMethod
::UserResource, IsLongString, ProcessedString, Params.CodePage
))) return Err;
;
1310
1311 for (auto Ch : ProcessedString) {
1312 if (IsLongString) {
1313 writeInt(Ch);
1314 continue;
1315 }
1316
1317 RETURN_IF_ERROR(checkNumberFits<uint8_t>(if (auto Err = (checkNumberFits<uint8_t>( Ch, "Character in narrow string in user-defined resource"
))) return Err;
1318 Ch, "Character in narrow string in user-defined resource"))if (auto Err = (checkNumberFits<uint8_t>( Ch, "Character in narrow string in user-defined resource"
))) return Err;
;
1319 writeInt<uint8_t>(Ch);
1320 }
1321 }
1322
1323 return Error::success();
1324}
1325
1326// --- VersionInfoResourceResource helpers. --- //
1327
1328Error ResourceFileWriter::writeVersionInfoBlock(const VersionInfoBlock &Blk) {
1329 // Output the header if the block has name.
1330 bool OutputHeader = Blk.Name != "";
1331 uint64_t LengthLoc;
1332
1333 padStream(sizeof(uint32_t));
1334 if (OutputHeader) {
1335 LengthLoc = writeInt<uint16_t>(0);
1336 writeInt<uint16_t>(0);
1337 writeInt<uint16_t>(1); // true
1338 RETURN_IF_ERROR(writeCString(Blk.Name))if (auto Err = (writeCString(Blk.Name))) return Err;;
1339 padStream(sizeof(uint32_t));
1340 }
1341
1342 for (const std::unique_ptr<VersionInfoStmt> &Item : Blk.Stmts) {
1343 VersionInfoStmt *ItemPtr = Item.get();
1344
1345 if (auto *BlockPtr = dyn_cast<VersionInfoBlock>(ItemPtr)) {
1346 RETURN_IF_ERROR(writeVersionInfoBlock(*BlockPtr))if (auto Err = (writeVersionInfoBlock(*BlockPtr))) return Err
;
;
1347 continue;
1348 }
1349
1350 auto *ValuePtr = cast<VersionInfoValue>(ItemPtr);
1351 RETURN_IF_ERROR(writeVersionInfoValue(*ValuePtr))if (auto Err = (writeVersionInfoValue(*ValuePtr))) return Err
;
;
1352 }
1353
1354 if (OutputHeader) {
1355 uint64_t CurLoc = tell();
1356 writeObjectAt(ulittle16_t(CurLoc - LengthLoc), LengthLoc);
1357 }
1358
1359 return Error::success();
1360}
1361
1362Error ResourceFileWriter::writeVersionInfoValue(const VersionInfoValue &Val) {
1363 // rc has a peculiar algorithm to output VERSIONINFO VALUEs. Each VALUE
1364 // is a mapping from the key (string) to the value (a sequence of ints or
1365 // a sequence of strings).
1366 //
1367 // If integers are to be written: width of each integer written depends on
1368 // whether it's been declared 'long' (it's DWORD then) or not (it's WORD).
1369 // ValueLength defined in structure referenced below is then the total
1370 // number of bytes taken by these integers.
1371 //
1372 // If strings are to be written: characters are always WORDs.
1373 // Moreover, '\0' character is written after the last string, and between
1374 // every two strings separated by comma (if strings are not comma-separated,
1375 // they're simply concatenated). ValueLength is equal to the number of WORDs
1376 // written (that is, half of the bytes written).
1377 //
1378 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms646994.aspx
1379 bool HasStrings = false, HasInts = false;
1380 for (auto &Item : Val.Values)
1381 (Item.isInt() ? HasInts : HasStrings) = true;
1382
1383 assert((HasStrings || HasInts) && "VALUE must have at least one argument")(((HasStrings || HasInts) && "VALUE must have at least one argument"
) ? static_cast<void> (0) : __assert_fail ("(HasStrings || HasInts) && \"VALUE must have at least one argument\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 1383, __PRETTY_FUNCTION__))
;
1384 if (HasStrings && HasInts)
1385 return createError(Twine("VALUE ") + Val.Key +
1386 " cannot contain both strings and integers");
1387
1388 padStream(sizeof(uint32_t));
1389 auto LengthLoc = writeInt<uint16_t>(0);
1390 auto ValLengthLoc = writeInt<uint16_t>(0);
1391 writeInt<uint16_t>(HasStrings);
1392 RETURN_IF_ERROR(writeCString(Val.Key))if (auto Err = (writeCString(Val.Key))) return Err;;
1393 padStream(sizeof(uint32_t));
1394
1395 auto DataLoc = tell();
1396 for (size_t Id = 0; Id < Val.Values.size(); ++Id) {
1397 auto &Item = Val.Values[Id];
1398 if (Item.isInt()) {
1399 auto Value = Item.getInt();
1400 RETURN_IF_ERROR(checkRCInt(Value, "VERSIONINFO integer value"))if (auto Err = (checkRCInt(Value, "VERSIONINFO integer value"
))) return Err;
;
1401 writeRCInt(Value);
1402 continue;
1403 }
1404
1405 bool WriteTerminator =
1406 Id == Val.Values.size() - 1 || Val.HasPrecedingComma[Id + 1];
1407 RETURN_IF_ERROR(writeCString(Item.getString(), WriteTerminator))if (auto Err = (writeCString(Item.getString(), WriteTerminator
))) return Err;
;
1408 }
1409
1410 auto CurLoc = tell();
1411 auto ValueLength = CurLoc - DataLoc;
1412 if (HasStrings) {
1413 assert(ValueLength % 2 == 0)((ValueLength % 2 == 0) ? static_cast<void> (0) : __assert_fail
("ValueLength % 2 == 0", "/build/llvm-toolchain-snapshot-8~svn345461/tools/llvm-rc/ResourceFileWriter.cpp"
, 1413, __PRETTY_FUNCTION__))
;
1414 ValueLength /= 2;
1415 }
1416 writeObjectAt(ulittle16_t(CurLoc - LengthLoc), LengthLoc);
1417 writeObjectAt(ulittle16_t(ValueLength), ValLengthLoc);
1418 return Error::success();
1419}
1420
1421template <typename Ty>
1422static Ty getWithDefault(const StringMap<Ty> &Map, StringRef Key,
1423 const Ty &Default) {
1424 auto Iter = Map.find(Key);
1425 if (Iter != Map.end())
1426 return Iter->getValue();
1427 return Default;
1428}
1429
1430Error ResourceFileWriter::writeVersionInfoBody(const RCResource *Base) {
1431 auto *Res = cast<VersionInfoResource>(Base);
1432
1433 const auto &FixedData = Res->FixedData;
1434
1435 struct /* VS_FIXEDFILEINFO */ {
1436 ulittle32_t Signature = ulittle32_t(0xFEEF04BD);
1437 ulittle32_t StructVersion = ulittle32_t(0x10000);
1438 // It's weird to have most-significant DWORD first on the little-endian
1439 // machines, but let it be this way.
1440 ulittle32_t FileVersionMS;
1441 ulittle32_t FileVersionLS;
1442 ulittle32_t ProductVersionMS;
1443 ulittle32_t ProductVersionLS;
1444 ulittle32_t FileFlagsMask;
1445 ulittle32_t FileFlags;
1446 ulittle32_t FileOS;
1447 ulittle32_t FileType;
1448 ulittle32_t FileSubtype;
1449 // MS implementation seems to always set these fields to 0.
1450 ulittle32_t FileDateMS = ulittle32_t(0);
1451 ulittle32_t FileDateLS = ulittle32_t(0);
1452 } FixedInfo;
1453
1454 // First, VS_VERSIONINFO.
1455 auto LengthLoc = writeInt<uint16_t>(0);
1456 writeInt<uint16_t>(sizeof(FixedInfo));
1457 writeInt<uint16_t>(0);
1458 cantFail(writeCString("VS_VERSION_INFO"));
1459 padStream(sizeof(uint32_t));
1460
1461 using VersionInfoFixed = VersionInfoResource::VersionInfoFixed;
1462 auto GetField = [&](VersionInfoFixed::VersionInfoFixedType Type) {
1463 static const SmallVector<uint32_t, 4> DefaultOut{0, 0, 0, 0};
1464 if (!FixedData.IsTypePresent[(int)Type])
1465 return DefaultOut;
1466 return FixedData.FixedInfo[(int)Type];
1467 };
1468
1469 auto FileVer = GetField(VersionInfoFixed::FtFileVersion);
1470 RETURN_IF_ERROR(checkNumberFits<uint16_t>(if (auto Err = (checkNumberFits<uint16_t>( *std::max_element
(FileVer.begin(), FileVer.end()), "FILEVERSION fields"))) return
Err;
1
Within the expansion of the macro 'RETURN_IF_ERROR':
a
Calling 'checkNumberFits<unsigned short>'
1471 *std::max_element(FileVer.begin(), FileVer.end()), "FILEVERSION fields"))if (auto Err = (checkNumberFits<uint16_t>( *std::max_element
(FileVer.begin(), FileVer.end()), "FILEVERSION fields"))) return
Err;
;
1472 FixedInfo.FileVersionMS = (FileVer[0] << 16) | FileVer[1];
1473 FixedInfo.FileVersionLS = (FileVer[2] << 16) | FileVer[3];
1474
1475 auto ProdVer = GetField(VersionInfoFixed::FtProductVersion);
1476 RETURN_IF_ERROR(checkNumberFits<uint16_t>(if (auto Err = (checkNumberFits<uint16_t>( *std::max_element
(ProdVer.begin(), ProdVer.end()), "PRODUCTVERSION fields"))) return
Err;
1477 *std::max_element(ProdVer.begin(), ProdVer.end()),if (auto Err = (checkNumberFits<uint16_t>( *std::max_element
(ProdVer.begin(), ProdVer.end()), "PRODUCTVERSION fields"))) return
Err;
1478 "PRODUCTVERSION fields"))if (auto Err = (checkNumberFits<uint16_t>( *std::max_element
(ProdVer.begin(), ProdVer.end()), "PRODUCTVERSION fields"))) return
Err;
;
1479 FixedInfo.ProductVersionMS = (ProdVer[0] << 16) | ProdVer[1];
1480 FixedInfo.ProductVersionLS = (ProdVer[2] << 16) | ProdVer[3];
1481
1482 FixedInfo.FileFlagsMask = GetField(VersionInfoFixed::FtFileFlagsMask)[0];
1483 FixedInfo.FileFlags = GetField(VersionInfoFixed::FtFileFlags)[0];
1484 FixedInfo.FileOS = GetField(VersionInfoFixed::FtFileOS)[0];
1485 FixedInfo.FileType = GetField(VersionInfoFixed::FtFileType)[0];
1486 FixedInfo.FileSubtype = GetField(VersionInfoFixed::FtFileSubtype)[0];
1487
1488 writeObject(FixedInfo);
1489 padStream(sizeof(uint32_t));
1490
1491 RETURN_IF_ERROR(writeVersionInfoBlock(Res->MainBlock))if (auto Err = (writeVersionInfoBlock(Res->MainBlock))) return
Err;
;
1492
1493 // FIXME: check overflow?
1494 writeObjectAt(ulittle16_t(tell() - LengthLoc), LengthLoc);
1495
1496 return Error::success();
1497}
1498
1499Expected<std::unique_ptr<MemoryBuffer>>
1500ResourceFileWriter::loadFile(StringRef File) const {
1501 SmallString<128> Path;
1502 SmallString<128> Cwd;
1503 std::unique_ptr<MemoryBuffer> Result;
1504
1505 // 1. The current working directory.
1506 sys::fs::current_path(Cwd);
1507 Path.assign(Cwd.begin(), Cwd.end());
1508 sys::path::append(Path, File);
1509 if (sys::fs::exists(Path))
1510 return errorOrToExpected(MemoryBuffer::getFile(Path, -1, false));
1511
1512 // 2. The directory of the input resource file, if it is different from the
1513 // current
1514 // working directory.
1515 StringRef InputFileDir = sys::path::parent_path(Params.InputFilePath);
1516 Path.assign(InputFileDir.begin(), InputFileDir.end());
1517 sys::path::append(Path, File);
1518 if (sys::fs::exists(Path))
1519 return errorOrToExpected(MemoryBuffer::getFile(Path, -1, false));
1520
1521 // 3. All of the include directories specified on the command line.
1522 for (StringRef ForceInclude : Params.Include) {
1523 Path.assign(ForceInclude.begin(), ForceInclude.end());
1524 sys::path::append(Path, File);
1525 if (sys::fs::exists(Path))
1526 return errorOrToExpected(MemoryBuffer::getFile(Path, -1, false));
1527 }
1528
1529 if (auto Result =
1530 llvm::sys::Process::FindInEnvPath("INCLUDE", File, Params.NoInclude))
1531 return errorOrToExpected(MemoryBuffer::getFile(*Result, -1, false));
1532
1533 return make_error<StringError>("error : file not found : " + Twine(File),
1534 inconvertibleErrorCode());
1535}
1536
1537} // namespace rc
1538} // namespace llvm

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

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