TypeLocBuilder.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //===--- TypeLocBuilder.cpp - Type Source Info collector ------------------===//
  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 files defines TypeLocBuilder, a class for building TypeLocs
  11. // bottom-up.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "TypeLocBuilder.h"
  15. using namespace clang;
  16. void TypeLocBuilder::pushFullCopy(TypeLoc L) {
  17. size_t Size = L.getFullDataSize();
  18. reserve(Size);
  19. SmallVector<TypeLoc, 4> TypeLocs;
  20. TypeLoc CurTL = L;
  21. while (CurTL) {
  22. TypeLocs.push_back(CurTL);
  23. CurTL = CurTL.getNextTypeLoc();
  24. }
  25. for (unsigned i = 0, e = TypeLocs.size(); i < e; ++i) {
  26. TypeLoc CurTL = TypeLocs[e-i-1];
  27. switch (CurTL.getTypeLocClass()) {
  28. #define ABSTRACT_TYPELOC(CLASS, PARENT)
  29. #define TYPELOC(CLASS, PARENT) \
  30. case TypeLoc::CLASS: { \
  31. CLASS##TypeLoc NewTL = push<class CLASS##TypeLoc>(CurTL.getType()); \
  32. memcpy(NewTL.getOpaqueData(), CurTL.getOpaqueData(), NewTL.getLocalDataSize()); \
  33. break; \
  34. }
  35. #include "clang/AST/TypeLocNodes.def"
  36. }
  37. }
  38. }
  39. void TypeLocBuilder::grow(size_t NewCapacity) {
  40. assert(NewCapacity > Capacity);
  41. // Allocate the new buffer and copy the old data into it.
  42. char *NewBuffer = new char[NewCapacity];
  43. unsigned NewIndex = Index + NewCapacity - Capacity;
  44. memcpy(&NewBuffer[NewIndex],
  45. &Buffer[Index],
  46. Capacity - Index);
  47. if (Buffer != InlineBuffer.buffer)
  48. delete[] Buffer;
  49. Buffer = NewBuffer;
  50. Capacity = NewCapacity;
  51. Index = NewIndex;
  52. }
  53. TypeLoc TypeLocBuilder::pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment) {
  54. #ifndef NDEBUG
  55. QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
  56. assert(TLast == LastTy &&
  57. "mismatch between last type and new type's inner type");
  58. LastTy = T;
  59. #endif
  60. assert(LocalAlignment <= BufferMaxAlignment && "Unexpected alignment");
  61. // If we need to grow, grow by a factor of 2.
  62. if (LocalSize > Index) {
  63. size_t RequiredCapacity = Capacity + (LocalSize - Index);
  64. size_t NewCapacity = Capacity * 2;
  65. while (RequiredCapacity > NewCapacity)
  66. NewCapacity *= 2;
  67. grow(NewCapacity);
  68. }
  69. // Because we're adding elements to the TypeLoc backwards, we have to
  70. // do some extra work to keep everything aligned appropriately.
  71. // FIXME: This algorithm is a absolute mess because every TypeLoc returned
  72. // needs to be valid. Partial TypeLocs are a terrible idea.
  73. // FIXME: 4 and 8 are sufficient at the moment, but it's pretty ugly to
  74. // hardcode them.
  75. if (LocalAlignment == 4) {
  76. if (NumBytesAtAlign8 == 0) {
  77. NumBytesAtAlign4 += LocalSize;
  78. } else {
  79. unsigned Padding = NumBytesAtAlign4 % 8;
  80. if (Padding == 0) {
  81. if (LocalSize % 8 == 0) {
  82. // Everything is set: there's no padding and we don't need to add
  83. // any.
  84. } else {
  85. assert(LocalSize % 8 == 4);
  86. // No existing padding; add in 4 bytes padding
  87. memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4);
  88. Index -= 4;
  89. }
  90. } else {
  91. assert(Padding == 4);
  92. if (LocalSize % 8 == 0) {
  93. // Everything is set: there's 4 bytes padding and we don't need
  94. // to add any.
  95. } else {
  96. assert(LocalSize % 8 == 4);
  97. // There are 4 bytes padding, but we don't need any; remove it.
  98. memmove(&Buffer[Index + 4], &Buffer[Index], NumBytesAtAlign4);
  99. Index += 4;
  100. }
  101. }
  102. NumBytesAtAlign4 += LocalSize;
  103. }
  104. } else if (LocalAlignment == 8) {
  105. if (!NumBytesAtAlign8 && NumBytesAtAlign4 % 8 != 0) {
  106. // No existing padding and misaligned members; add in 4 bytes padding
  107. memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4);
  108. Index -= 4;
  109. }
  110. // Forget about any padding.
  111. NumBytesAtAlign4 = 0;
  112. NumBytesAtAlign8 += LocalSize;
  113. } else {
  114. assert(LocalSize == 0);
  115. }
  116. Index -= LocalSize;
  117. assert(Capacity - Index == TypeLoc::getFullDataSizeForType(T) &&
  118. "incorrect data size provided to CreateTypeSourceInfo!");
  119. return getTemporaryTypeLoc(T);
  120. }