| 237 | } |
| 238 | |
| 239 | static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { |
| 240 | if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) |
| 241 | return error("Invalid record"); |
| 242 | |
| 243 | SmallVector<uint64_t, 64> Record; |
| 244 | // Read all the records for this module. |
| 245 | |
| 246 | while (true) { |
| 247 | BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
| 248 | |
| 249 | switch (Entry.Kind) { |
| 250 | case BitstreamEntry::SubBlock: // Handled for us already. |
| 251 | case BitstreamEntry::Error: |
| 252 | return error("Malformed block"); |
| 253 | case BitstreamEntry::EndBlock: |
| 254 | return false; |
| 255 | case BitstreamEntry::Record: |
| 256 | // The interesting case. |
| 257 | break; |
| 258 | } |
| 259 | |
| 260 | // Read a record. |
| 261 | switch (Stream.readRecord(Entry.ID, Record)) { |
| 262 | default: |
| 263 | break; // Default behavior, ignore unknown content. |
| 264 | case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] |
| 265 | std::string S; |
| 266 | if (convertToString(Record, 0, S)) |
| 267 | return error("Invalid record"); |
| 268 | // Check for the i386 and other (x86_64, ARM) conventions |
| 269 | if (S.find("__DATA,__objc_catlist") != std::string::npos || |
| 270 | S.find("__OBJC,__category") != std::string::npos) |
| 271 | return true; |
| 272 | break; |
| 273 | } |
| 274 | } |
| 275 | Record.clear(); |
| 276 | } |
| 277 | llvm_unreachable("Exit infinite loop"); |
| 278 | } |
| 279 | |
| 280 | static Expected<bool> hasObjCCategory(BitstreamCursor &Stream) { |
| 281 | // We expect a number of well-defined blocks, though we don't necessarily |
no test coverage detected