| 436 | |
| 437 | template <class BTyFunc, class PtrTyFunc> |
| 438 | std::string getFormatDescriptorImpl(Type const* Ty, BTyFunc BTyFormat, PtrTyFunc PtrTyFormat) |
| 439 | { |
| 440 | switch (Ty->getKind()) { |
| 441 | case Type::TY_Enum: |
| 442 | Ty = cast<EnumType>(Ty)->getBasicType(); |
| 443 | case Type::TY_Basic: |
| 444 | return BTyFormat(cast<BasicType>(Ty)); |
| 445 | case Type::TY_Pointer: |
| 446 | return PtrTyFormat(cast<PointerType>(Ty)); |
| 447 | case Type::TY_Struct: |
| 448 | { |
| 449 | std::string Ret; |
| 450 | auto* STy = cast<StructType>(Ty); |
| 451 | size_t CurIdx = 0; |
| 452 | for (auto const& F: STy->getOrgFields()) { |
| 453 | const size_t Off = F.getOffset(); |
| 454 | const auto* FTy = F.getType(); |
| 455 | if (CurIdx < Off) { |
| 456 | // Padding |
| 457 | for (size_t i = 0; i < (Off-CurIdx); ++i) Ret += "x"; |
| 458 | } |
| 459 | Ret += getFormatDescriptorImpl(FTy, BTyFormat, PtrTyFormat); |
| 460 | CurIdx = F.getOffset() + FTy->getSize(); |
| 461 | } |
| 462 | // Final padding |
| 463 | for (size_t i = 0; i < (STy->getSize()-CurIdx); ++i) Ret += "x"; |
| 464 | return Ret; |
| 465 | } |
| 466 | default: |
| 467 | break; |
| 468 | }; |
| 469 | |
| 470 | // We treat every other cases as buffer of bytes. |
| 471 | return std::to_string(Ty->getSize()) + "B"; |
| 472 | } |
| 473 | |
| 474 | } // anonymous |
| 475 |
no test coverage detected