Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 //===- NaClBitcodeMungeUtils.h - Munge bitcode records --------*- 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 utility class NaClMungedBitcode to edit a base | |
| 11 // sequence of PNaCl bitcode records. It is intended to be used for | |
| 12 // both unit testing, and for fuzzing bitcode files. | |
| 13 // | |
| 14 // The editing actions are defined in terms of the base sequence of | |
| 15 // bitcode records, and do not actually modify that base sequence. As | |
| 16 // such, all edits are defined relative to a record index in the base | |
| 17 // sequence of bitcode records. Using record indices into the base | |
| 18 // sequence means that succeeding edits need not modify record indices | |
| 19 // based on the effects of preceding edits. Rather, the record index | |
| 20 // remains constant across all editing actions. | |
| 21 // | |
| 22 // There are two steps in creating munged bitcode. The first step | |
| 23 // defines the initial (base) sequence of bitcode records to be | |
| 24 // edited. The second is to apply editing actions to the base sequence | |
| 25 // of records. | |
| 26 // | |
| 27 // Defining the initial sequence of bitcode records is done by | |
| 28 // using NaClMungedBitcode's constructor. | |
| 29 // | |
| 30 // There are four kinds of editing actions: | |
| 31 // | |
| 32 // 1) Add a record before a (base) record index. | |
| 33 // 2) Add a record after a (base) record index. | |
| 34 // 3) Remove a record at a (base) record index. | |
| 35 // 4) Replace a record at a (base) record index. | |
| 36 // | |
| 37 // Each of the editing actions are defined by the methods addBefore(), | |
| 38 // addAfter(), remove(), and replace(). The edited sequence of records | |
| 39 // is defined by an iterator, and is accessible using methods begin() | |
| 40 // and end(). | |
| 41 // | |
| 42 // If multiple records are added before/after a record index, the | |
| 43 // order of the added records correspond to the order they were added. | |
| 44 // | |
| 45 // For unit testing, simple array interfaces are provided. The first | |
| 46 // interface defines the initial base sequence of bitcode records. The | |
| 47 // second interface, method munge(), defines a sequence of editing | |
| 48 // actions to apply to the base sequence of records. | |
| 49 // | |
| 50 // These arrays are defined using type uint64_t. A bitcode record is | |
| 51 // defined as a sequence of values of the form: | |
| 52 // | |
| 53 // AbbrevIndex, RecordCode, Value1, ..., ValueN , Terminator | |
| 54 // | |
| 55 // Terminator is a (user-specified) designated constant used to mark | |
| 56 // the end of bitcode records. A record can contain zero or more | |
| 57 // values. | |
| 58 // | |
| 59 // An editing action is defined as one of the following sequences of | |
| 60 // values: | |
| 61 // | |
| 62 // RecordIndex, AddBefore, AbbrevIndex, RecordCode, Value, ..., Terminator | |
| 63 // RecordIndex, AddAfter, AbbrevIndex, RecordCode, Value, ..., Terminator | |
| 64 // RecordIndex, Remove | |
| 65 // RecordIndex, Replace, AbbrevIndex, RecordCode, Value, ..., Terminator. | |
| 66 // | |
| 67 // RecordIndex defines where the action applies, relative to the base | |
| 68 // sequence of records. EditAction defines the editing action to | |
| 69 // apply. The remaining fields define an optional record associated | |
| 70 // with the editing action. | |
| 71 // | |
| 72 // ===---------------------------------------------------------------------===// | |
|
Karl
2016/05/10 14:49:48
Is this file really needed?
It is only used in a
Jim Stichnoth
2016/05/10 18:11:48
Done.
| |
| 73 | |
| 74 #ifndef LLVM_BITCODE_NACL_NACLBITCODEMUNGEUTILS_H | |
| 75 #define LLVM_BITCODE_NACL_NACLBITCODEMUNGEUTILS_H | |
| 76 | |
| 77 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" | |
| 78 #include "llvm/Support/MemoryBuffer.h" | |
| 79 | |
| 80 #include <list> | |
| 81 #include <map> | |
| 82 | |
| 83 namespace llvm { | |
| 84 | |
| 85 class NaClBitcodeAbbrevRecord; // bitcode record. | |
| 86 class NaClMungedBitcodeIter; // iterator over edited bitcode records. | |
| 87 | |
| 88 /// \brief Defines a list of bitcode records. | |
| 89 typedef std::vector<std::unique_ptr<NaClBitcodeAbbrevRecord>> | |
| 90 NaClBitcodeRecordList; | |
| 91 | |
| 92 // TODO(kschimpf): Modify following two methods to return error_code. | |
| 93 | |
| 94 /// \brief Extracts out the records in Records, and puts them into RecordList. | |
| 95 /// | |
| 96 /// \brief RecordList[in/out] Record list to read into. | |
| 97 /// \brief Records Array containing data defining records. | |
| 98 /// \brief RecordsSize The size of array Records. | |
| 99 /// \brief RecordTerminator The value used to terminate records. | |
| 100 void readNaClBitcodeRecordList(NaClBitcodeRecordList &RecordList, | |
| 101 const uint64_t Records[], | |
| 102 size_t RecordsSize, | |
| 103 uint64_t RecordTerminator); | |
| 104 | |
| 105 /// Read in the list of records from binary bitcode from a memory buffer. | |
| 106 void readNaClBitcodeRecordList(NaClBitcodeRecordList &RecordList, | |
| 107 std::unique_ptr<MemoryBuffer> InputBuffer); | |
| 108 | |
| 109 /// Read in the list of records from textual bitcode from a memory buffer. | |
| 110 std::error_code readNaClTextBcRecordList( | |
| 111 NaClBitcodeRecordList &RecordList, | |
| 112 std::unique_ptr<MemoryBuffer> InputBuffer); | |
| 113 | |
| 114 /// Read textual bitcode records from Filename, and fill Buffer with | |
| 115 /// corresponding bitcode. Return error_code describing success of | |
| 116 /// read. Verbose (if not nullptr) is used to generate more human | |
| 117 /// readable error messages than the text in the returned error | |
| 118 /// message. | |
| 119 std::error_code readNaClRecordTextAndBuildBitcode( | |
| 120 StringRef Filename, SmallVectorImpl<char> &Buffer, | |
| 121 raw_ostream *Verbose = nullptr); | |
| 122 | |
| 123 /// Write out RecordList (as text) to Buffer. Returns true when | |
| 124 /// successful. Error message are written to ErrStream. | |
| 125 bool writeNaClBitcodeRecordList(NaClBitcodeRecordList &RecordList, | |
| 126 SmallVectorImpl<char> &Buffer, | |
| 127 raw_ostream &ErrStream); | |
| 128 | |
| 129 /// \brief An edited (i.e. munged) list of bitcode records. Edits are | |
| 130 /// always relative to the initial list of records. | |
| 131 class NaClMungedBitcode { | |
| 132 friend class NaClMungedBitcodeIter; | |
| 133 NaClMungedBitcode() = delete; | |
| 134 NaClMungedBitcode(const NaClMungedBitcode &) = delete; | |
| 135 NaClMungedBitcode &operator=(const NaClMungedBitcode &) = delete; | |
| 136 | |
| 137 public: | |
| 138 /// \brief Iterator over edited records. | |
| 139 typedef NaClMungedBitcodeIter iterator; | |
| 140 | |
| 141 /// \brief Read in initial list of records from bitcode in a memory buffer. | |
| 142 explicit NaClMungedBitcode(std::unique_ptr<MemoryBuffer> InputBuffer, | |
| 143 bool ReadAsText=false) | |
| 144 : BaseRecords(new NaClBitcodeRecordList()) { | |
| 145 if (ReadAsText) | |
| 146 readNaClTextBcRecordList(*BaseRecords, std::move(InputBuffer)); | |
| 147 else | |
| 148 readNaClBitcodeRecordList(*BaseRecords, std::move(InputBuffer)); | |
| 149 } | |
| 150 | |
| 151 /// \brief Initialize the list of records to be edited. | |
| 152 explicit NaClMungedBitcode(std::unique_ptr<NaClBitcodeRecordList> BaseRecords) | |
| 153 : BaseRecords(std::move(BaseRecords)) {} | |
| 154 | |
| 155 /// \brief Initialize the list of records to be edited using | |
| 156 /// array specification. | |
| 157 /// | |
| 158 /// \brief Records Array containing data defining records. | |
| 159 /// \brief RecordsSize The size of array Records. | |
| 160 /// \brief RecordTerminator The value used to terminate records. | |
| 161 NaClMungedBitcode(const uint64_t Records[], size_t RecordsSize, | |
| 162 uint64_t RecordTerminator); | |
| 163 | |
| 164 ~NaClMungedBitcode(); | |
| 165 | |
| 166 /// \brief Iterator pointing to first record in edited records. | |
| 167 NaClMungedBitcodeIter begin() const; | |
| 168 | |
| 169 /// \brief Iterator pointing after last record in edited records. | |
| 170 NaClMungedBitcodeIter end() const; | |
| 171 | |
| 172 /// \brief Insert Record immediately before the record at RecordIndex. | |
| 173 /// | |
| 174 /// \param RecordIndex The index (within BaseRecords) to add before. | |
| 175 /// \param Record The record to add. | |
| 176 void addBefore(size_t RecordIndex, NaClBitcodeAbbrevRecord &Record); | |
| 177 | |
| 178 /// \brief Insert Record after the record at RecordIndex (and after | |
| 179 /// any previously added after records for RecordIndex). | |
| 180 /// | |
| 181 /// \param RecordIndex The index (within BaseRecords) to add after. | |
| 182 /// \param Record The record to add. | |
| 183 void addAfter(size_t RecordIndex, NaClBitcodeAbbrevRecord &Record); | |
| 184 | |
| 185 /// \brief Remove the record at RecordIndex. Note that because | |
| 186 /// the record index is based on the base records, and those records | |
| 187 /// are not modified, this editing action effectively undoes all | |
| 188 /// previous remove/replace editing actions for this index. | |
| 189 void remove(size_t RecordIndex); | |
| 190 | |
| 191 /// \brief Replace the record at RecordIndex with Record. Note that | |
| 192 /// because the record index is based on the base records, and those | |
| 193 /// records are not modified, this editing action effectively undoes | |
| 194 /// all previous remove/replace editing actions for this index. | |
| 195 void replace(size_t RecordIndex, NaClBitcodeAbbrevRecord &Record); | |
| 196 | |
| 197 /// \brief Print out the resulting edited list of records. | |
| 198 void print(raw_ostream &Out) const; | |
| 199 | |
| 200 /// Defines set of possible write flags. | |
| 201 struct WriteFlags { | |
| 202 /// True if error recovery should be applied. | |
| 203 bool getTryToRecover() const { return TryToRecover; } | |
| 204 | |
| 205 /// Define that error recovery should be applied when writing. | |
| 206 void setTryToRecover(bool NewValue) { | |
| 207 TryToRecover = NewValue; | |
| 208 assert(!(TryToRecover && WriteBadAbbrevIndex)); | |
| 209 } | |
| 210 | |
| 211 /// True if a bad abbreviation index should be written (rather than | |
| 212 /// trying error recovery) so that bitcode readers can be tested for | |
| 213 /// this condition. | |
| 214 bool getWriteBadAbbrevIndex() const { return WriteBadAbbrevIndex; } | |
| 215 | |
| 216 /// Define that the first bad abbreviation index should be written, | |
| 217 /// and corresponding minimal context added so that the bitcode can | |
| 218 /// be used to test reading the erroneous written bitcode. | |
| 219 void setWriteBadAbbrevIndex(bool NewValue) { | |
| 220 WriteBadAbbrevIndex = NewValue; | |
| 221 assert(!(TryToRecover && WriteBadAbbrevIndex)); | |
| 222 } | |
| 223 | |
| 224 /// Get the stream to print errors while writing bitcode. | |
| 225 raw_ostream &getErrStream() const { | |
| 226 return ErrStream ? *ErrStream : errs(); | |
| 227 } | |
| 228 | |
| 229 /// Set the stream to print errors to. | |
| 230 void setErrStream(raw_ostream &NewValue) { | |
| 231 ErrStream = &NewValue; | |
| 232 } | |
| 233 | |
| 234 void reset() { | |
| 235 TryToRecover = false; | |
| 236 WriteBadAbbrevIndex = false; | |
| 237 ErrStream = nullptr; | |
| 238 } | |
| 239 | |
| 240 private: | |
| 241 bool TryToRecover = false; | |
| 242 bool WriteBadAbbrevIndex = false; | |
| 243 raw_ostream *ErrStream = nullptr; | |
| 244 }; | |
| 245 | |
| 246 /// Defines the results associated with writing bitcode. | |
| 247 struct WriteResults { | |
| 248 /// Number of errors generated. | |
| 249 size_t NumErrors = 0; | |
| 250 /// Number of repairs (via error recovery) that were applied. | |
| 251 size_t NumRepairs = 0; | |
| 252 /// True if a bad abbreviation index were written. | |
| 253 bool WroteBadAbbrevIndex = false; | |
| 254 }; | |
| 255 | |
| 256 /// \brief Write out the edited list of bitcode records using | |
| 257 /// the given buffer. | |
| 258 /// | |
| 259 /// \param Buffer The buffer to write into. | |
| 260 /// \param AddHeader Add header block when true. | |
| 261 /// \param Flags Write flags to use. | |
| 262 /// | |
| 263 /// \return Returns the results of the write. | |
| 264 WriteResults writeMaybeRepair( | |
| 265 SmallVectorImpl<char> &Buffer, bool AddHeader, | |
| 266 const WriteFlags &Flags) const; | |
| 267 | |
| 268 bool write(SmallVectorImpl<char> &Buffer, bool AddHeader, | |
| 269 const WriteFlags &Flags) const { | |
| 270 WriteResults Results = writeMaybeRepair(Buffer, AddHeader, Flags); | |
| 271 return Results.NumErrors == 0 | |
| 272 || (Flags.getTryToRecover() && Results.NumErrors == Results.NumRepairs); | |
| 273 } | |
| 274 | |
| 275 bool write(SmallVectorImpl<char> &Buffer, bool AddHeader) const { | |
| 276 WriteFlags Flags; | |
| 277 return write(Buffer, AddHeader, Flags); | |
| 278 } | |
| 279 | |
| 280 /// \brief The types of editing actions that can be applied. | |
| 281 enum EditAction { | |
| 282 AddBefore, // Insert new record before base record at index. | |
| 283 AddAfter, // Insert new record after base record at index. | |
| 284 Remove, // Remove record at index. | |
| 285 Replace // Replace base record at index with new record. | |
| 286 }; | |
| 287 | |
| 288 /// \brief Apply a set of edits defined in the given array. | |
| 289 /// | |
| 290 /// Actions are a sequence of values, followed by a (common) | |
| 291 /// terminator value. Valid action sequences are: | |
| 292 /// | |
| 293 /// RecordIndex AddBefore Abbrev Code Values Terminator | |
| 294 /// | |
| 295 /// RecordIndex AddAfter Abbrev Code Values Terminator | |
| 296 /// | |
| 297 /// RecordIndex Remove | |
| 298 /// | |
| 299 /// RecordIndex Replace Abbrev Code Values Terminator | |
| 300 /// | |
| 301 /// \param Munges The array containing the edits to apply. | |
| 302 /// \param MungesSize The size of Munges. | |
| 303 /// \param Terminator The value used to terminate records in editing actions. | |
| 304 void munge(const uint64_t Munges[], size_t MungesSize, uint64_t Terminator); | |
| 305 | |
| 306 /// \brief Removes all editing actions and resets back to the original | |
| 307 /// set of base records. | |
| 308 void removeEdits(); | |
| 309 | |
| 310 /// Returns the unedited list of bitcode records. | |
| 311 const NaClBitcodeRecordList &getBaseRecords() const { | |
| 312 return *BaseRecords; | |
| 313 } | |
| 314 | |
| 315 private: | |
| 316 typedef std::list<NaClBitcodeAbbrevRecord *> RecordListType; | |
| 317 typedef std::map<size_t, RecordListType *> InsertionsMapType; | |
| 318 typedef std::map<size_t, NaClBitcodeAbbrevRecord *> ReplaceMapType; | |
| 319 | |
| 320 /// \brief The list of base records that will be edited. | |
| 321 std::unique_ptr<NaClBitcodeRecordList> BaseRecords; | |
| 322 // Holds map from record index to list of records added before | |
| 323 // the corresponding record in the list of base records. | |
| 324 InsertionsMapType BeforeInsertionsMap; | |
| 325 // Holds map from record index to the list of records added after | |
| 326 // the corresponding record in the list of base records. | |
| 327 InsertionsMapType AfterInsertionsMap; | |
| 328 // Holds map from record index to the record that replaces the | |
| 329 // corresponding record in the list of base records. Note: If the | |
| 330 // range is the nullptr, it corresponds to a remove instead of a | |
| 331 // replace. | |
| 332 ReplaceMapType ReplaceMap; | |
| 333 | |
| 334 // Returns the list of records associated with Index in Map. | |
| 335 RecordListType &at(InsertionsMapType &Map, size_t Index) { | |
| 336 InsertionsMapType::iterator Pos = Map.find(Index); | |
| 337 if (Pos == Map.end()) { | |
| 338 RecordListType *List = new RecordListType(); | |
| 339 Map.emplace(Index, List); | |
| 340 return *List; | |
| 341 } | |
| 342 return *Pos->second; | |
| 343 } | |
| 344 | |
| 345 // Creates a (heap allocated) copy of the given record. | |
| 346 NaClBitcodeAbbrevRecord *copy(const NaClBitcodeAbbrevRecord &Record); | |
| 347 | |
| 348 // Delete nested objects within insertions map. | |
| 349 void destroyInsertionsMap(NaClMungedBitcode::InsertionsMapType &Map); | |
| 350 }; | |
| 351 | |
| 352 /// \brief Defines a bitcode record with its associated abbreviation index. | |
| 353 class NaClBitcodeAbbrevRecord : public NaClBitcodeRecordData { | |
| 354 NaClBitcodeAbbrevRecord &operator=(NaClBitcodeAbbrevRecord &) = delete; | |
| 355 | |
| 356 public: | |
| 357 /// \brief The abbreviation associated with the bitcode record. | |
| 358 unsigned Abbrev; | |
| 359 | |
| 360 /// \brief Creates a bitcode record. | |
| 361 /// | |
| 362 /// \param Abbrev Abbreviation index associated with record. | |
| 363 /// \param Code The selector code of the record. | |
| 364 /// \param Values The values associated with the selector code. | |
| 365 NaClBitcodeAbbrevRecord(unsigned Abbrev, unsigned Code, | |
| 366 const NaClRecordVector &Values) | |
| 367 : NaClBitcodeRecordData(Code, Values), Abbrev(Abbrev) {} | |
| 368 | |
| 369 /// \brief Creates a copy of the given abbreviated bitcode record. | |
| 370 explicit NaClBitcodeAbbrevRecord(const NaClBitcodeAbbrevRecord &Rcd) | |
| 371 : NaClBitcodeRecordData(Rcd), Abbrev(Rcd.Abbrev) {} | |
| 372 | |
| 373 /// \brief Creates a default abbreviated bitcode record. | |
| 374 NaClBitcodeAbbrevRecord() : Abbrev(naclbitc::UNABBREV_RECORD) {} | |
| 375 | |
| 376 ~NaClBitcodeAbbrevRecord() {} | |
| 377 | |
| 378 /// \brief Replaces the contents of the abbreviated bitcode record with | |
| 379 /// the corresponding contents in the array. | |
| 380 /// | |
| 381 /// \param Values The array to get values from. | |
| 382 /// \param ValuesSize The length of the Values array. | |
| 383 /// \param Terminator The value defining the end of the record in Values. | |
| 384 /// \param Index The index of the first value to be used in Values. | |
| 385 void read(const uint64_t Values[], size_t ValuesSize, | |
| 386 const uint64_t Terminator, size_t &Index); | |
| 387 | |
| 388 void print(raw_ostream &out) const; | |
| 389 }; | |
| 390 | |
| 391 inline raw_ostream &operator<<(raw_ostream &Out, | |
| 392 const NaClBitcodeAbbrevRecord &Record) { | |
| 393 Record.print(Out); | |
| 394 return Out; | |
| 395 } | |
| 396 | |
| 397 /// \brief Defines an iterator to walk over elements of an edited | |
| 398 /// record list. | |
| 399 class NaClMungedBitcodeIter { | |
| 400 | |
| 401 public: | |
| 402 /// \brief Returns an iterator pointing to the first record in the | |
| 403 /// edited list of records. | |
| 404 static NaClMungedBitcodeIter begin(const NaClMungedBitcode &MungedBitcode) { | |
| 405 return NaClMungedBitcodeIter(MungedBitcode, 0); | |
| 406 } | |
| 407 | |
| 408 /// \brief Returns an iterator pointing past the last record in the | |
| 409 /// edited list of records. | |
| 410 static NaClMungedBitcodeIter end(const NaClMungedBitcode &MungedBitcode) { | |
| 411 return NaClMungedBitcodeIter(MungedBitcode, | |
| 412 MungedBitcode.BaseRecords->size()); | |
| 413 } | |
| 414 | |
| 415 bool operator==(const NaClMungedBitcodeIter &Iter) const; | |
| 416 | |
| 417 bool operator!=(const NaClMungedBitcodeIter &Iter) const { | |
| 418 return !operator==(Iter); | |
| 419 } | |
| 420 | |
| 421 /// \brief Advances the iterator over one record in the list of | |
| 422 /// edited records. | |
| 423 NaClMungedBitcodeIter &operator++(); | |
| 424 | |
| 425 /// \brief Returns the bitcode record the iterator is before. | |
| 426 NaClBitcodeAbbrevRecord &operator*(); | |
| 427 | |
| 428 private: | |
| 429 /// \brief Defines position of the iterator, relative to the corresponding | |
| 430 /// record index in the base list of records. | |
| 431 enum MungedPosition { | |
| 432 /// Processing the list of records inserted before the record | |
| 433 /// index of the base list of records. | |
| 434 InBeforeInsertions, | |
| 435 /// Processing the record at the given record index of the base | |
| 436 /// list of records. | |
| 437 AtIndex, | |
| 438 /// Processing the list of records inserted after the record index | |
| 439 /// of the base list of records. | |
| 440 InAfterInsertions, | |
| 441 }; | |
| 442 | |
| 443 // The edited list of records to iterate over. | |
| 444 const NaClMungedBitcode *MungedBitcode; | |
| 445 // The corresponding index, wrt to the edited list of records, that | |
| 446 // is being processed. | |
| 447 size_t Index; | |
| 448 // The position of the iterator wrt to Index. | |
| 449 MungedPosition Position; | |
| 450 // An iterator defining the current position within a | |
| 451 // BeforeInsertions or AfterInsertions list. When the iterator is | |
| 452 // not in the corresponding position (i.e. InBeforeInsertions or | |
| 453 // InAfterInsertions) this iterator is undefined. | |
| 454 NaClMungedBitcode::RecordListType::const_iterator InsertionsIter; | |
| 455 // An iterator defining the end position of the corresponding list | |
| 456 // of records defined by InsertionsIter. Only defined when | |
| 457 // InsertionsIter is defined. | |
| 458 NaClMungedBitcode::RecordListType::const_iterator InsertionsIterEnd; | |
| 459 // Dummy list to initialize InsertionsIter if no such list exists. | |
| 460 NaClMungedBitcode::RecordListType EmptyList; | |
| 461 | |
| 462 // \brief Defines an iterator at the beginning of the | |
| 463 // BeforeInsertions list associated with the given Index in | |
| 464 // MungedBitcode. | |
| 465 NaClMungedBitcodeIter(const NaClMungedBitcode &MungedBitcode, size_t Index) | |
| 466 : MungedBitcode(&MungedBitcode), Index(Index), | |
| 467 Position(InBeforeInsertions), InsertionsIter(), InsertionsIterEnd() { | |
| 468 placeAt(MungedBitcode.BeforeInsertionsMap, 0); | |
| 469 updatePosition(); | |
| 470 } | |
| 471 | |
| 472 // \brief Places the corresponding insertions iterator based on the | |
| 473 // list of records defined at Index for the given insertions Map. | |
| 474 void placeAt(const NaClMungedBitcode::InsertionsMapType &Map, size_t Index) { | |
| 475 NaClMungedBitcode::InsertionsMapType::const_iterator Pos = Map.find(Index); | |
| 476 if (Pos == Map.end()) { | |
| 477 InsertionsIter = EmptyList.end(); | |
| 478 InsertionsIterEnd = EmptyList.end(); | |
| 479 } else { | |
| 480 InsertionsIter = Pos->second->begin(); | |
| 481 InsertionsIterEnd = Pos->second->end(); | |
| 482 } | |
| 483 } | |
| 484 | |
| 485 // \brief Moves the iterator to the position of the next edited | |
| 486 // record. | |
| 487 void updatePosition(); | |
| 488 }; | |
| 489 | |
| 490 } // end namespace llvm. | |
| 491 | |
| 492 #endif // LLVM_BITCODE_NACL_NACLBITCODEMUNGE_H | |
| OLD | NEW |