Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===//
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 file defines the NestedNameSpecifier class, which represents
10
//  a C++ nested-name-specifier.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/NestedNameSpecifier.h"
15
#include "clang/AST/ASTContext.h"
16
#include "clang/AST/Decl.h"
17
#include "clang/AST/DeclCXX.h"
18
#include "clang/AST/DeclTemplate.h"
19
#include "clang/AST/PrettyPrinter.h"
20
#include "clang/AST/TemplateName.h"
21
#include "clang/AST/Type.h"
22
#include "clang/AST/TypeLoc.h"
23
#include "clang/Basic/LLVM.h"
24
#include "clang/Basic/LangOptions.h"
25
#include "clang/Basic/SourceLocation.h"
26
#include "llvm/ADT/FoldingSet.h"
27
#include "llvm/ADT/SmallVector.h"
28
#include "llvm/Support/Casting.h"
29
#include "llvm/Support/Compiler.h"
30
#include "llvm/Support/ErrorHandling.h"
31
#include "llvm/Support/raw_ostream.h"
32
#include <algorithm>
33
#include <cassert>
34
#include <cstdlib>
35
#include <cstring>
36
37
using namespace clang;
38
39
NestedNameSpecifier *
40
NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
41
12.7M
                                  const NestedNameSpecifier &Mockup) {
42
12.7M
  llvm::FoldingSetNodeID ID;
43
12.7M
  Mockup.Profile(ID);
44
12.7M
45
12.7M
  void *InsertPos = nullptr;
46
12.7M
  NestedNameSpecifier *NNS
47
12.7M
    = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
48
12.7M
  if (!NNS) {
49
5.25M
    NNS =
50
5.25M
        new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup);
51
5.25M
    Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
52
5.25M
  }
53
12.7M
54
12.7M
  return NNS;
55
12.7M
}
56
57
NestedNameSpecifier *
58
NestedNameSpecifier::Create(const ASTContext &Context,
59
95.2k
                            NestedNameSpecifier *Prefix, IdentifierInfo *II) {
60
95.2k
  assert(II && "Identifier cannot be NULL");
61
95.2k
  assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
62
95.2k
63
95.2k
  NestedNameSpecifier Mockup;
64
95.2k
  Mockup.Prefix.setPointer(Prefix);
65
95.2k
  Mockup.Prefix.setInt(StoredIdentifier);
66
95.2k
  Mockup.Specifier = II;
67
95.2k
  return FindOrInsert(Context, Mockup);
68
95.2k
}
69
70
NestedNameSpecifier *
71
NestedNameSpecifier::Create(const ASTContext &Context,
72
                            NestedNameSpecifier *Prefix,
73
2.18M
                            const NamespaceDecl *NS) {
74
2.18M
  assert(NS && "Namespace cannot be NULL");
75
2.18M
  assert((!Prefix ||
76
2.18M
          (Prefix->getAsType() == nullptr &&
77
2.18M
           Prefix->getAsIdentifier() == nullptr)) &&
78
2.18M
         "Broken nested name specifier");
79
2.18M
  NestedNameSpecifier Mockup;
80
2.18M
  Mockup.Prefix.setPointer(Prefix);
81
2.18M
  Mockup.Prefix.setInt(StoredDecl);
82
2.18M
  Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
83
2.18M
  return FindOrInsert(Context, Mockup);
84
2.18M
}
85
86
NestedNameSpecifier *
87
NestedNameSpecifier::Create(const ASTContext &Context,
88
                            NestedNameSpecifier *Prefix,
89
332
                            NamespaceAliasDecl *Alias) {
90
332
  assert(Alias && "Namespace alias cannot be NULL");
91
332
  assert((!Prefix ||
92
332
          (Prefix->getAsType() == nullptr &&
93
332
           Prefix->getAsIdentifier() == nullptr)) &&
94
332
         "Broken nested name specifier");
95
332
  NestedNameSpecifier Mockup;
96
332
  Mockup.Prefix.setPointer(Prefix);
97
332
  Mockup.Prefix.setInt(StoredDecl);
98
332
  Mockup.Specifier = Alias;
99
332
  return FindOrInsert(Context, Mockup);
100
332
}
101
102
NestedNameSpecifier *
103
NestedNameSpecifier::Create(const ASTContext &Context,
104
                            NestedNameSpecifier *Prefix,
105
10.5M
                            bool Template, const Type *T) {
106
10.5M
  assert(T && "Type cannot be NULL");
107
10.5M
  NestedNameSpecifier Mockup;
108
10.5M
  Mockup.Prefix.setPointer(Prefix);
109
10.5M
  Mockup.Prefix.setInt(Template? 
StoredTypeSpecWithTemplate1.16k
:
StoredTypeSpec10.5M
);
110
10.5M
  Mockup.Specifier = const_cast<Type*>(T);
111
10.5M
  return FindOrInsert(Context, Mockup);
112
10.5M
}
113
114
NestedNameSpecifier *
115
0
NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
116
0
  assert(II && "Identifier cannot be NULL");
117
0
  NestedNameSpecifier Mockup;
118
0
  Mockup.Prefix.setPointer(nullptr);
119
0
  Mockup.Prefix.setInt(StoredIdentifier);
120
0
  Mockup.Specifier = II;
121
0
  return FindOrInsert(Context, Mockup);
122
0
}
123
124
NestedNameSpecifier *
125
258k
NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
126
258k
  if (!Context.GlobalNestedNameSpecifier)
127
2.47k
    Context.GlobalNestedNameSpecifier =
128
2.47k
        new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier();
129
258k
  return Context.GlobalNestedNameSpecifier;
130
258k
}
131
132
NestedNameSpecifier *
133
NestedNameSpecifier::SuperSpecifier(const ASTContext &Context,
134
58
                                    CXXRecordDecl *RD) {
135
58
  NestedNameSpecifier Mockup;
136
58
  Mockup.Prefix.setPointer(nullptr);
137
58
  Mockup.Prefix.setInt(StoredDecl);
138
58
  Mockup.Specifier = RD;
139
58
  return FindOrInsert(Context, Mockup);
140
58
}
141
142
130M
NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
143
130M
  if (!Specifier)
144
6.54M
    return Global;
145
123M
146
123M
  switch (Prefix.getInt()) {
147
123M
  case StoredIdentifier:
148
266k
    return Identifier;
149
123M
150
123M
  case StoredDecl: {
151
32.0M
    NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
152
32.0M
    if (isa<CXXRecordDecl>(ND))
153
1.07k
      return Super;
154
32.0M
    return isa<NamespaceDecl>(ND) ? 
Namespace32.0M
:
NamespaceAlias8.42k
;
155
32.0M
  }
156
32.0M
157
91.3M
  case StoredTypeSpec:
158
91.3M
    return TypeSpec;
159
32.0M
160
32.0M
  case StoredTypeSpecWithTemplate:
161
22.6k
    return TypeSpecWithTemplate;
162
0
  }
163
0
164
0
  llvm_unreachable("Invalid NNS Kind!");
165
0
}
166
167
/// Retrieve the namespace stored in this nested name specifier.
168
3.59M
NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
169
3.59M
  if (Prefix.getInt() == StoredDecl)
170
3.59M
    return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
171
405
172
405
  return nullptr;
173
405
}
174
175
/// Retrieve the namespace alias stored in this nested name specifier.
176
940
NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
177
940
  if (Prefix.getInt() == StoredDecl)
178
577
    return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
179
363
180
363
  return nullptr;
181
363
}
182
183
/// Retrieve the record declaration stored in this nested name specifier.
184
120k
CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
185
120k
  switch (Prefix.getInt()) {
186
120k
  case StoredIdentifier:
187
0
    return nullptr;
188
120k
189
120k
  case StoredDecl:
190
119
    return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
191
120k
192
120k
  case StoredTypeSpec:
193
120k
  case StoredTypeSpecWithTemplate:
194
120k
    return getAsType()->getAsCXXRecordDecl();
195
0
  }
196
0
197
0
  llvm_unreachable("Invalid NNS Kind!");
198
0
}
199
200
/// Whether this nested name specifier refers to a dependent
201
/// type or not.
202
17.3M
bool NestedNameSpecifier::isDependent() const {
203
17.3M
  switch (getKind()) {
204
17.3M
  case Identifier:
205
73.6k
    // Identifier specifiers always represent dependent types
206
73.6k
    return true;
207
17.3M
208
17.3M
  case Namespace:
209
4.50M
  case NamespaceAlias:
210
4.50M
  case Global:
211
4.50M
    return false;
212
4.50M
213
4.50M
  case Super: {
214
199
    CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
215
199
    for (const auto &Base : RD->bases())
216
204
      if (Base.getType()->isDependentType())
217
91
        return true;
218
199
219
199
    
return false108
;
220
199
  }
221
199
222
12.7M
  case TypeSpec:
223
12.7M
  case TypeSpecWithTemplate:
224
12.7M
    return getAsType()->isDependentType();
225
0
  }
226
0
227
0
  llvm_unreachable("Invalid NNS Kind!");
228
0
}
229
230
/// Whether this nested name specifier refers to a dependent
231
/// type or not.
232
4.42M
bool NestedNameSpecifier::isInstantiationDependent() const {
233
4.42M
  switch (getKind()) {
234
4.42M
  case Identifier:
235
8.63k
    // Identifier specifiers always represent dependent types
236
8.63k
    return true;
237
4.42M
238
4.42M
  case Namespace:
239
930k
  case NamespaceAlias:
240
930k
  case Global:
241
930k
  case Super:
242
930k
    return false;
243
930k
244
3.48M
  case TypeSpec:
245
3.48M
  case TypeSpecWithTemplate:
246
3.48M
    return getAsType()->isInstantiationDependentType();
247
0
  }
248
0
249
0
  llvm_unreachable("Invalid NNS Kind!");
250
0
}
251
252
6.41M
bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
253
6.41M
  switch (getKind()) {
254
6.41M
  case Identifier:
255
17.7k
    return getPrefix() && 
getPrefix()->containsUnexpandedParameterPack()17.6k
;
256
6.41M
257
6.41M
  case Namespace:
258
1.04M
  case NamespaceAlias:
259
1.04M
  case Global:
260
1.04M
  case Super:
261
1.04M
    return false;
262
1.04M
263
5.35M
  case TypeSpec:
264
5.35M
  case TypeSpecWithTemplate:
265
5.35M
    return getAsType()->containsUnexpandedParameterPack();
266
0
  }
267
0
268
0
  llvm_unreachable("Invalid NNS Kind!");
269
0
}
270
271
/// Print this nested name specifier to the given output
272
/// stream.
273
void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
274
156k
                                bool ResolveTemplateArguments) const {
275
156k
  if (getPrefix())
276
34.9k
    getPrefix()->print(OS, Policy);
277
156k
278
156k
  switch (getKind()) {
279
156k
  case Identifier:
280
15
    OS << getAsIdentifier()->getName();
281
15
    break;
282
156k
283
156k
  case Namespace:
284
36.7k
    if (getAsNamespace()->isAnonymousNamespace())
285
0
      return;
286
36.7k
287
36.7k
    OS << getAsNamespace()->getName();
288
36.7k
    break;
289
36.7k
290
36.7k
  case NamespaceAlias:
291
16
    OS << getAsNamespaceAlias()->getName();
292
16
    break;
293
36.7k
294
36.7k
  case Global:
295
372
    break;
296
36.7k
297
36.7k
  case Super:
298
16
    OS << "__super";
299
16
    break;
300
36.7k
301
36.7k
  case TypeSpecWithTemplate:
302
17
    OS << "template ";
303
17
    // Fall through to print the type.
304
17
    LLVM_FALLTHROUGH;
305
17
306
118k
  case TypeSpec: {
307
118k
    const auto *Record =
308
118k
            dyn_cast_or_null<ClassTemplateSpecializationDecl>(getAsRecordDecl());
309
118k
    if (ResolveTemplateArguments && 
Record115k
) {
310
115k
        // Print the type trait with resolved template parameters.
311
115k
        Record->printName(OS);
312
115k
        printTemplateArgumentList(OS, Record->getTemplateArgs().asArray(),
313
115k
                                  Policy);
314
115k
        break;
315
115k
    }
316
3.82k
    const Type *T = getAsType();
317
3.82k
318
3.82k
    PrintingPolicy InnerPolicy(Policy);
319
3.82k
    InnerPolicy.SuppressScope = true;
320
3.82k
321
3.82k
    // Nested-name-specifiers are intended to contain minimally-qualified
322
3.82k
    // types. An actual ElaboratedType will not occur, since we'll store
323
3.82k
    // just the type that is referred to in the nested-name-specifier (e.g.,
324
3.82k
    // a TypedefType, TagType, etc.). However, when we are dealing with
325
3.82k
    // dependent template-id types (e.g., Outer<T>::template Inner<U>),
326
3.82k
    // the type requires its own nested-name-specifier for uniqueness, so we
327
3.82k
    // suppress that nested-name-specifier during printing.
328
3.82k
    assert(!isa<ElaboratedType>(T) &&
329
3.82k
           "Elaborated type in nested-name-specifier");
330
3.82k
    if (const TemplateSpecializationType *SpecType
331
1.14k
          = dyn_cast<TemplateSpecializationType>(T)) {
332
1.14k
      // Print the template name without its corresponding
333
1.14k
      // nested-name-specifier.
334
1.14k
      SpecType->getTemplateName().print(OS, InnerPolicy, true);
335
1.14k
336
1.14k
      // Print the template argument list.
337
1.14k
      printTemplateArgumentList(OS, SpecType->template_arguments(),
338
1.14k
                                InnerPolicy);
339
2.68k
    } else {
340
2.68k
      // Print the type normally
341
2.68k
      QualType(T, 0).print(OS, InnerPolicy);
342
2.68k
    }
343
3.82k
    break;
344
3.82k
  }
345
156k
  }
346
156k
347
156k
  OS << "::";
348
156k
}
349
350
0
LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const {
351
0
  dump(llvm::errs(), LO);
352
0
}
353
354
0
LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { dump(llvm::errs()); }
355
356
0
LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS) const {
357
0
  LangOptions LO;
358
0
  dump(OS, LO);
359
0
}
360
361
LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS,
362
0
                                                const LangOptions &LO) const {
363
0
  print(OS, PrintingPolicy(LO));
364
0
}
365
366
unsigned
367
20.7M
NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
368
20.7M
  assert(Qualifier && "Expected a non-NULL qualifier");
369
20.7M
370
20.7M
  // Location of the trailing '::'.
371
20.7M
  unsigned Length = sizeof(unsigned);
372
20.7M
373
20.7M
  switch (Qualifier->getKind()) {
374
20.7M
  case NestedNameSpecifier::Global:
375
367k
    // Nothing more to add.
376
367k
    break;
377
20.7M
378
20.7M
  case NestedNameSpecifier::Identifier:
379
8.38M
  case NestedNameSpecifier::Namespace:
380
8.38M
  case NestedNameSpecifier::NamespaceAlias:
381
8.38M
  case NestedNameSpecifier::Super:
382
8.38M
    // The location of the identifier or namespace name.
383
8.38M
    Length += sizeof(unsigned);
384
8.38M
    break;
385
8.38M
386
11.9M
  case NestedNameSpecifier::TypeSpecWithTemplate:
387
11.9M
  case NestedNameSpecifier::TypeSpec:
388
11.9M
    // The "void*" that points at the TypeLoc data.
389
11.9M
    // Note: the 'template' keyword is part of the TypeLoc.
390
11.9M
    Length += sizeof(void *);
391
11.9M
    break;
392
20.7M
  }
393
20.7M
394
20.7M
  return Length;
395
20.7M
}
396
397
unsigned
398
75.1M
NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) {
399
75.1M
  unsigned Length = 0;
400
95.8M
  for (; Qualifier; 
Qualifier = Qualifier->getPrefix()20.7M
)
401
20.7M
    Length += getLocalDataLength(Qualifier);
402
75.1M
  return Length;
403
75.1M
}
404
405
/// Load a (possibly unaligned) source location from a given address
406
/// and offset.
407
72.7M
static SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
408
72.7M
  unsigned Raw;
409
72.7M
  memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
410
72.7M
  return SourceLocation::getFromRawEncoding(Raw);
411
72.7M
}
412
413
/// Load a (possibly unaligned) pointer from a given address and
414
/// offset.
415
43.2M
static void *LoadPointer(void *Data, unsigned Offset) {
416
43.2M
  void *Result;
417
43.2M
  memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
418
43.2M
  return Result;
419
43.2M
}
420
421
25.2M
SourceRange NestedNameSpecifierLoc::getSourceRange() const {
422
25.2M
  if (!Qualifier)
423
297k
    return SourceRange();
424
24.9M
425
24.9M
  NestedNameSpecifierLoc First = *this;
426
29.5M
  while (NestedNameSpecifierLoc Prefix = First.getPrefix())
427
4.59M
    First = Prefix;
428
24.9M
429
24.9M
  return SourceRange(First.getLocalSourceRange().getBegin(),
430
24.9M
                     getLocalSourceRange().getEnd());
431
24.9M
}
432
433
57.9M
SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
434
57.9M
  if (!Qualifier)
435
0
    return SourceRange();
436
57.9M
437
57.9M
  unsigned Offset = getDataLength(Qualifier->getPrefix());
438
57.9M
  switch (Qualifier->getKind()) {
439
57.9M
  case NestedNameSpecifier::Global:
440
3.71M
    return LoadSourceLocation(Data, Offset);
441
57.9M
442
57.9M
  case NestedNameSpecifier::Identifier:
443
14.7M
  case NestedNameSpecifier::Namespace:
444
14.7M
  case NestedNameSpecifier::NamespaceAlias:
445
14.7M
  case NestedNameSpecifier::Super:
446
14.7M
    return SourceRange(LoadSourceLocation(Data, Offset),
447
14.7M
                       LoadSourceLocation(Data, Offset + sizeof(unsigned)));
448
14.7M
449
39.4M
  case NestedNameSpecifier::TypeSpecWithTemplate:
450
39.4M
  case NestedNameSpecifier::TypeSpec: {
451
39.4M
    // The "void*" that points at the TypeLoc data.
452
39.4M
    // Note: the 'template' keyword is part of the TypeLoc.
453
39.4M
    void *TypeData = LoadPointer(Data, Offset);
454
39.4M
    TypeLoc TL(Qualifier->getAsType(), TypeData);
455
39.4M
    return SourceRange(TL.getBeginLoc(),
456
39.4M
                       LoadSourceLocation(Data, Offset + sizeof(void*)));
457
0
  }
458
0
  }
459
0
460
0
  llvm_unreachable("Invalid NNS Kind!");
461
0
}
462
463
3.76M
TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
464
3.76M
  if (Qualifier->getKind() != NestedNameSpecifier::TypeSpec &&
465
3.76M
      
Qualifier->getKind() != NestedNameSpecifier::TypeSpecWithTemplate3.44k
)
466
0
    return TypeLoc();
467
3.76M
468
3.76M
  // The "void*" that points at the TypeLoc data.
469
3.76M
  unsigned Offset = getDataLength(Qualifier->getPrefix());
470
3.76M
  void *TypeData = LoadPointer(Data, Offset);
471
3.76M
  return TypeLoc(Qualifier->getAsType(), TypeData);
472
3.76M
}
473
474
static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
475
17.6M
              unsigned &BufferCapacity) {
476
17.6M
  if (Start == End)
477
12
    return;
478
17.6M
479
17.6M
  if (BufferSize + (End - Start) > BufferCapacity) {
480
9.15M
    // Reallocate the buffer.
481
9.15M
    unsigned NewCapacity = std::max(
482
9.15M
        (unsigned)(BufferCapacity ? 
BufferCapacity * 2330k
:
sizeof(void *) * 28.82M
),
483
9.15M
        (unsigned)(BufferSize + (End - Start)));
484
9.15M
    char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity));
485
9.15M
    if (BufferCapacity) {
486
330k
      memcpy(NewBuffer, Buffer, BufferSize);
487
330k
      free(Buffer);
488
330k
    }
489
9.15M
    Buffer = NewBuffer;
490
9.15M
    BufferCapacity = NewCapacity;
491
9.15M
  }
492
17.6M
493
17.6M
  memcpy(Buffer + BufferSize, Start, End - Start);
494
17.6M
  BufferSize += End-Start;
495
17.6M
}
496
497
/// Save a source location to the given buffer.
498
static void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
499
10.2M
                               unsigned &BufferSize, unsigned &BufferCapacity) {
500
10.2M
  unsigned Raw = Loc.getRawEncoding();
501
10.2M
  Append(reinterpret_cast<char *>(&Raw),
502
10.2M
         reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
503
10.2M
         Buffer, BufferSize, BufferCapacity);
504
10.2M
}
505
506
/// Save a pointer to the given buffer.
507
static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
508
5.91M
                        unsigned &BufferCapacity) {
509
5.91M
  Append(reinterpret_cast<char *>(&Ptr),
510
5.91M
         reinterpret_cast<char *>(&Ptr) + sizeof(void *),
511
5.91M
         Buffer, BufferSize, BufferCapacity);
512
5.91M
}
513
514
NestedNameSpecifierLocBuilder::
515
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
516
18.4M
    : Representation(Other.Representation) {
517
18.4M
  if (!Other.Buffer)
518
17.2M
    return;
519
1.20M
520
1.20M
  if (Other.BufferCapacity == 0) {
521
27.0k
    // Shallow copy is okay.
522
27.0k
    Buffer = Other.Buffer;
523
27.0k
    BufferSize = Other.BufferSize;
524
27.0k
    return;
525
27.0k
  }
526
1.17M
527
1.17M
  // Deep copy
528
1.17M
  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
529
1.17M
         BufferCapacity);
530
1.17M
}
531
532
NestedNameSpecifierLocBuilder &
533
NestedNameSpecifierLocBuilder::
534
1.92M
operator=(const NestedNameSpecifierLocBuilder &Other) {
535
1.92M
  Representation = Other.Representation;
536
1.92M
537
1.92M
  if (Buffer && 
Other.Buffer12
&&
BufferCapacity >= Other.BufferSize12
) {
538
0
    // Re-use our storage.
539
0
    BufferSize = Other.BufferSize;
540
0
    memcpy(Buffer, Other.Buffer, BufferSize);
541
0
    return *this;
542
0
  }
543
1.92M
544
1.92M
  // Free our storage, if we have any.
545
1.92M
  if (BufferCapacity) {
546
0
    free(Buffer);
547
0
    BufferCapacity = 0;
548
0
  }
549
1.92M
550
1.92M
  if (!Other.Buffer) {
551
1.49M
    // Empty.
552
1.49M
    Buffer = nullptr;
553
1.49M
    BufferSize = 0;
554
1.49M
    return *this;
555
1.49M
  }
556
427k
557
427k
  if (Other.BufferCapacity == 0) {
558
157k
    // Shallow copy is okay.
559
157k
    Buffer = Other.Buffer;
560
157k
    BufferSize = Other.BufferSize;
561
157k
    return *this;
562
157k
  }
563
270k
564
270k
  // Deep copy.
565
270k
  BufferSize = 0;
566
270k
  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
567
270k
         BufferCapacity);
568
270k
  return *this;
569
270k
}
570
571
void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
572
                                           SourceLocation TemplateKWLoc,
573
                                           TypeLoc TL,
574
5.63M
                                           SourceLocation ColonColonLoc) {
575
5.63M
  Representation = NestedNameSpecifier::Create(Context, Representation,
576
5.63M
                                               TemplateKWLoc.isValid(),
577
5.63M
                                               TL.getTypePtr());
578
5.63M
579
5.63M
  // Push source-location info into the buffer.
580
5.63M
  SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
581
5.63M
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
582
5.63M
}
583
584
void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
585
                                           IdentifierInfo *Identifier,
586
                                           SourceLocation IdentifierLoc,
587
12.8k
                                           SourceLocation ColonColonLoc) {
588
12.8k
  Representation = NestedNameSpecifier::Create(Context, Representation,
589
12.8k
                                               Identifier);
590
12.8k
591
12.8k
  // Push source-location info into the buffer.
592
12.8k
  SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
593
12.8k
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
594
12.8k
}
595
596
void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
597
                                           NamespaceDecl *Namespace,
598
                                           SourceLocation NamespaceLoc,
599
2.04M
                                           SourceLocation ColonColonLoc) {
600
2.04M
  Representation = NestedNameSpecifier::Create(Context, Representation,
601
2.04M
                                               Namespace);
602
2.04M
603
2.04M
  // Push source-location info into the buffer.
604
2.04M
  SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
605
2.04M
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
606
2.04M
}
607
608
void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
609
                                           NamespaceAliasDecl *Alias,
610
                                           SourceLocation AliasLoc,
611
328
                                           SourceLocation ColonColonLoc) {
612
328
  Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
613
328
614
328
  // Push source-location info into the buffer.
615
328
  SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
616
328
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
617
328
}
618
619
void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
620
252k
                                               SourceLocation ColonColonLoc) {
621
252k
  assert(!Representation && "Already have a nested-name-specifier!?");
622
252k
  Representation = NestedNameSpecifier::GlobalSpecifier(Context);
623
252k
624
252k
  // Push source-location info into the buffer.
625
252k
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
626
252k
}
627
628
void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context,
629
                                              CXXRecordDecl *RD,
630
                                              SourceLocation SuperLoc,
631
58
                                              SourceLocation ColonColonLoc) {
632
58
  Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
633
58
634
58
  // Push source-location info into the buffer.
635
58
  SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
636
58
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
637
58
}
638
639
void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
640
                                                NestedNameSpecifier *Qualifier,
641
285k
                                                SourceRange R) {
642
285k
  Representation = Qualifier;
643
285k
644
285k
  // Construct bogus (but well-formed) source information for the
645
285k
  // nested-name-specifier.
646
285k
  BufferSize = 0;
647
285k
  SmallVector<NestedNameSpecifier *, 4> Stack;
648
571k
  for (NestedNameSpecifier *NNS = Qualifier; NNS; 
NNS = NNS->getPrefix()286k
)
649
286k
    Stack.push_back(NNS);
650
571k
  while (!Stack.empty()) {
651
286k
    NestedNameSpecifier *NNS = Stack.pop_back_val();
652
286k
    switch (NNS->getKind()) {
653
286k
      case NestedNameSpecifier::Identifier:
654
5.82k
      case NestedNameSpecifier::Namespace:
655
5.82k
      case NestedNameSpecifier::NamespaceAlias:
656
5.82k
        SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
657
5.82k
        break;
658
5.82k
659
279k
      case NestedNameSpecifier::TypeSpec:
660
279k
      case NestedNameSpecifier::TypeSpecWithTemplate: {
661
279k
        TypeSourceInfo *TSInfo
662
279k
        = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
663
279k
                                           R.getBegin());
664
279k
        SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
665
279k
                    BufferCapacity);
666
279k
        break;
667
279k
      }
668
279k
669
279k
      case NestedNameSpecifier::Global:
670
371
      case NestedNameSpecifier::Super:
671
371
        break;
672
286k
    }
673
286k
674
286k
    // Save the location of the '::'.
675
286k
    SaveSourceLocation(Stack.empty()? 
R.getEnd()283k
:
R.getBegin()2.57k
,
676
286k
                       Buffer, BufferSize, BufferCapacity);
677
286k
  }
678
285k
}
679
680
9.90M
void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
681
9.90M
  if (BufferCapacity)
682
215k
    free(Buffer);
683
9.90M
684
9.90M
  if (!Other) {
685
0
    Representation = nullptr;
686
0
    BufferSize = 0;
687
0
    return;
688
0
  }
689
9.90M
690
9.90M
  // Rather than copying the data (which is wasteful), "adopt" the
691
9.90M
  // pointer (which points into the ASTContext) but set the capacity to zero to
692
9.90M
  // indicate that we don't own it.
693
9.90M
  Representation = Other.getNestedNameSpecifier();
694
9.90M
  Buffer = static_cast<char *>(Other.getOpaqueData());
695
9.90M
  BufferSize = Other.getDataLength();
696
9.90M
  BufferCapacity = 0;
697
9.90M
}
698
699
NestedNameSpecifierLoc
700
9.10M
NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const {
701
9.10M
  if (!Representation)
702
19.9k
    return NestedNameSpecifierLoc();
703
9.08M
704
9.08M
  // If we adopted our data pointer from elsewhere in the AST context, there's
705
9.08M
  // no need to copy the memory.
706
9.08M
  if (BufferCapacity == 0)
707
3.71M
    return NestedNameSpecifierLoc(Representation, Buffer);
708
5.37M
709
5.37M
  // FIXME: After copying the source-location information, should we free
710
5.37M
  // our (temporary) buffer and adopt the ASTContext-allocated memory?
711
5.37M
  // Doing so would optimize repeated calls to getWithLocInContext().
712
5.37M
  void *Mem = Context.Allocate(BufferSize, alignof(void *));
713
5.37M
  memcpy(Mem, Buffer, BufferSize);
714
5.37M
  return NestedNameSpecifierLoc(Representation, Mem);
715
5.37M
}