Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Sema/TypeLocBuilder.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- TypeLocBuilder.cpp - Type Source Info collector ------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This files defines TypeLocBuilder, a class for building TypeLocs
10
//  bottom-up.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "TypeLocBuilder.h"
15
16
using namespace clang;
17
18
348k
void TypeLocBuilder::pushFullCopy(TypeLoc L) {
19
348k
  size_t Size = L.getFullDataSize();
20
348k
  reserve(Size);
21
348k
22
348k
  SmallVector<TypeLoc, 4> TypeLocs;
23
348k
  TypeLoc CurTL = L;
24
732k
  while (CurTL) {
25
384k
    TypeLocs.push_back(CurTL);
26
384k
    CurTL = CurTL.getNextTypeLoc();
27
384k
  }
28
348k
29
732k
  for (unsigned i = 0, e = TypeLocs.size(); i < e; 
++i384k
) {
30
384k
    TypeLoc CurTL = TypeLocs[e-i-1];
31
384k
    switch (CurTL.getTypeLocClass()) {
32
0
#define ABSTRACT_TYPELOC(CLASS, PARENT)
33
0
#define TYPELOC(CLASS, PARENT) \
34
384k
    case TypeLoc::CLASS: { \
35
384k
      CLASS##TypeLoc NewTL = push<class CLASS##TypeLoc>(CurTL.getType()); \
36
384k
      memcpy(NewTL.getOpaqueData(), CurTL.getOpaqueData(), NewTL.getLocalDataSize()); \
37
384k
      break; \
38
384k
    }
39
0
#include "clang/AST/TypeLocNodes.def"
40
384k
    }
41
384k
  }
42
348k
}
43
44
6.49M
void TypeLocBuilder::grow(size_t NewCapacity) {
45
6.49M
  assert(NewCapacity > Capacity);
46
6.49M
47
6.49M
  // Allocate the new buffer and copy the old data into it.
48
6.49M
  char *NewBuffer = new char[NewCapacity];
49
6.49M
  unsigned NewIndex = Index + NewCapacity - Capacity;
50
6.49M
  memcpy(&NewBuffer[NewIndex],
51
6.49M
         &Buffer[Index],
52
6.49M
         Capacity - Index);
53
6.49M
54
6.49M
  if (Buffer != InlineBuffer)
55
61.0k
    delete[] Buffer;
56
6.49M
57
6.49M
  Buffer = NewBuffer;
58
6.49M
  Capacity = NewCapacity;
59
6.49M
  Index = NewIndex;
60
6.49M
}
61
62
18.1M
TypeLoc TypeLocBuilder::pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment) {
63
18.1M
#ifndef NDEBUG
64
18.1M
  QualType TLast = TypeLoc(T, nullptr).getNextTypeLoc().getType();
65
18.1M
  assert(TLast == LastTy &&
66
18.1M
         "mismatch between last type and new type's inner type");
67
18.1M
  LastTy = T;
68
18.1M
#endif
69
18.1M
70
18.1M
  assert(LocalAlignment <= BufferMaxAlignment && "Unexpected alignment");
71
18.1M
72
18.1M
  // If we need to grow, grow by a factor of 2.
73
18.1M
  if (LocalSize > Index) {
74
4.64M
    size_t RequiredCapacity = Capacity + (LocalSize - Index);
75
4.64M
    size_t NewCapacity = Capacity * 2;
76
5.06M
    while (RequiredCapacity > NewCapacity)
77
425k
      NewCapacity *= 2;
78
4.64M
    grow(NewCapacity);
79
4.64M
  }
80
18.1M
81
18.1M
  // Because we're adding elements to the TypeLoc backwards, we have to
82
18.1M
  // do some extra work to keep everything aligned appropriately.
83
18.1M
  // FIXME: This algorithm is a absolute mess because every TypeLoc returned
84
18.1M
  // needs to be valid.  Partial TypeLocs are a terrible idea.
85
18.1M
  // FIXME: 4 and 8 are sufficient at the moment, but it's pretty ugly to
86
18.1M
  // hardcode them.
87
18.1M
  if (LocalAlignment == 4) {
88
10.0M
    if (NumBytesAtAlign8 == 0) {
89
9.85M
      NumBytesAtAlign4 += LocalSize;
90
9.85M
    } else {
91
237k
      unsigned Padding = NumBytesAtAlign4 % 8;
92
237k
      if (Padding == 0) {
93
236k
        if (LocalSize % 8 == 0) {
94
4.44k
          // Everything is set: there's no padding and we don't need to add
95
4.44k
          // any.
96
231k
        } else {
97
231k
          assert(LocalSize % 8 == 4);
98
231k
          // No existing padding; add in 4 bytes padding
99
231k
          memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4);
100
231k
          Index -= 4;
101
231k
        }
102
236k
      } else {
103
1.23k
        assert(Padding == 4);
104
1.23k
        if (LocalSize % 8 == 0) {
105
0
          // Everything is set: there's 4 bytes padding and we don't need
106
0
          // to add any.
107
1.23k
        } else {
108
1.23k
          assert(LocalSize % 8 == 4);
109
1.23k
          // There are 4 bytes padding, but we don't need any; remove it.
110
1.23k
          memmove(&Buffer[Index + 4], &Buffer[Index], NumBytesAtAlign4);
111
1.23k
          Index += 4;
112
1.23k
        }
113
1.23k
      }
114
237k
      NumBytesAtAlign4 += LocalSize;
115
237k
    }
116
10.0M
  } else 
if (8.02M
LocalAlignment == 88.02M
) {
117
8.01M
    if (NumBytesAtAlign8 == 0) {
118
7.83M
      // We have not seen any 8-byte aligned element yet. We insert a padding
119
7.83M
      // only if the new Index is not 8-byte-aligned.
120
7.83M
      if ((Index - LocalSize) % 8 != 0) {
121
1.12M
        memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4);
122
1.12M
        Index -= 4;
123
1.12M
      }
124
7.83M
    } else {
125
184k
      unsigned Padding = NumBytesAtAlign4 % 8;
126
184k
      if (Padding == 0) {
127
172k
        if (LocalSize % 8 == 0) {
128
172k
          // Everything is set: there's no padding and we don't need to add
129
172k
          // any.
130
172k
        } else {
131
0
          assert(LocalSize % 8 == 4);
132
0
          // No existing padding; add in 4 bytes padding
133
0
          memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4);
134
0
          Index -= 4;
135
0
        }
136
172k
      } else {
137
12.2k
        assert(Padding == 4);
138
12.2k
        if (LocalSize % 8 == 0) {
139
12.2k
          // Everything is set: there's 4 bytes padding and we don't need
140
12.2k
          // to add any.
141
12.2k
        } else {
142
0
          assert(LocalSize % 8 == 4);
143
0
          // There are 4 bytes padding, but we don't need any; remove it.
144
0
          memmove(&Buffer[Index + 4], &Buffer[Index], NumBytesAtAlign4);
145
0
          Index += 4;
146
0
        }
147
12.2k
      }
148
184k
    }
149
8.01M
150
8.01M
    // Forget about any padding.
151
8.01M
    NumBytesAtAlign4 = 0;
152
8.01M
    NumBytesAtAlign8 += LocalSize;
153
8.01M
  } else {
154
7.64k
    assert(LocalSize == 0);
155
7.64k
  }
156
18.1M
157
18.1M
  Index -= LocalSize;
158
18.1M
159
18.1M
  assert(Capacity - Index == TypeLoc::getFullDataSizeForType(T) &&
160
18.1M
         "incorrect data size provided to CreateTypeSourceInfo!");
161
18.1M
162
18.1M
  return getTemporaryTypeLoc(T);
163
18.1M
}