Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Index/USRGeneration.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- USRGeneration.cpp - Routines for USR generation --------------------===//
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
#include "clang/Index/USRGeneration.h"
10
#include "clang/AST/ASTContext.h"
11
#include "clang/AST/DeclTemplate.h"
12
#include "clang/AST/DeclVisitor.h"
13
#include "clang/Lex/PreprocessingRecord.h"
14
#include "llvm/Support/Path.h"
15
#include "llvm/Support/raw_ostream.h"
16
17
using namespace clang;
18
using namespace clang::index;
19
20
//===----------------------------------------------------------------------===//
21
// USR generation.
22
//===----------------------------------------------------------------------===//
23
24
/// \returns true on error.
25
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
26
2.60k
                     const SourceManager &SM, bool IncludeOffset) {
27
2.60k
  if (Loc.isInvalid()) {
28
0
    return true;
29
0
  }
30
2.60k
  Loc = SM.getExpansionLoc(Loc);
31
2.60k
  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
32
2.60k
  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
33
2.60k
  if (FE) {
34
2.21k
    OS << llvm::sys::path::filename(FE->getName());
35
2.21k
  } else {
36
391
    // This case really isn't interesting.
37
391
    return true;
38
391
  }
39
2.21k
  if (IncludeOffset) {
40
1.72k
    // Use the offest into the FileID to represent the location.  Using
41
1.72k
    // a line/column can cause us to look back at the original source file,
42
1.72k
    // which is expensive.
43
1.72k
    OS << '@' << Decomposed.second;
44
1.72k
  }
45
2.21k
  return false;
46
2.21k
}
47
48
19.0k
static StringRef GetExternalSourceContainer(const NamedDecl *D) {
49
19.0k
  if (!D)
50
1.10k
    return StringRef();
51
17.9k
  if (auto *attr = D->getExternalSourceSymbolAttr()) {
52
36
    return attr->getDefinedIn();
53
36
  }
54
17.8k
  return StringRef();
55
17.8k
}
56
57
namespace {
58
class USRGenerator : public ConstDeclVisitor<USRGenerator> {
59
  SmallVectorImpl<char> &Buf;
60
  llvm::raw_svector_ostream Out;
61
  bool IgnoreResults;
62
  ASTContext *Context;
63
  bool generatedLoc;
64
65
  llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
66
67
public:
68
  explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf)
69
  : Buf(Buf),
70
    Out(Buf),
71
    IgnoreResults(false),
72
    Context(Ctx),
73
    generatedLoc(false)
74
18.7k
  {
75
18.7k
    // Add the USR space prefix.
76
18.7k
    Out << getUSRSpacePrefix();
77
18.7k
  }
78
79
18.7k
  bool ignoreResults() const { return IgnoreResults; }
80
81
  // Visitation methods from generating USRs from AST elements.
82
  void VisitDeclContext(const DeclContext *D);
83
  void VisitFieldDecl(const FieldDecl *D);
84
  void VisitFunctionDecl(const FunctionDecl *D);
85
  void VisitNamedDecl(const NamedDecl *D);
86
  void VisitNamespaceDecl(const NamespaceDecl *D);
87
  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
88
  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
89
  void VisitClassTemplateDecl(const ClassTemplateDecl *D);
90
  void VisitObjCContainerDecl(const ObjCContainerDecl *CD,
91
                              const ObjCCategoryDecl *CatD = nullptr);
92
  void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
93
  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
94
  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
95
  void VisitTagDecl(const TagDecl *D);
96
  void VisitTypedefDecl(const TypedefDecl *D);
97
  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
98
  void VisitVarDecl(const VarDecl *D);
99
  void VisitBindingDecl(const BindingDecl *D);
100
  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
101
  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
102
  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
103
  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
104
105
1
  void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
106
1
    IgnoreResults = true; // No USRs for linkage specs themselves.
107
1
  }
108
109
1
  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
110
1
    IgnoreResults = true;
111
1
  }
112
113
2
  void VisitUsingDecl(const UsingDecl *D) {
114
2
    VisitDeclContext(D->getDeclContext());
115
2
    Out << "@UD@";
116
2
117
2
    bool EmittedDeclName = !EmitDeclName(D);
118
2
    assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls");
119
2
    (void)EmittedDeclName;
120
2
  }
121
122
  bool ShouldGenerateLocation(const NamedDecl *D);
123
124
1.55k
  bool isLocal(const NamedDecl *D) {
125
1.55k
    return D->getParentFunctionOrMethod() != nullptr;
126
1.55k
  }
127
128
  void GenExtSymbolContainer(const NamedDecl *D);
129
130
  /// Generate the string component containing the location of the
131
  ///  declaration.
132
  bool GenLoc(const Decl *D, bool IncludeOffset);
133
134
  /// String generation methods used both by the visitation methods
135
  /// and from other clients that want to directly generate USRs.  These
136
  /// methods do not construct complete USRs (which incorporate the parents
137
  /// of an AST element), but only the fragments concerning the AST element
138
  /// itself.
139
140
  /// Generate a USR for an Objective-C class.
141
  void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
142
1.13k
                    StringRef CategoryContextExtSymbolDefinedIn) {
143
1.13k
    generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
144
1.13k
                            CategoryContextExtSymbolDefinedIn);
145
1.13k
  }
146
147
  /// Generate a USR for an Objective-C class category.
148
  void GenObjCCategory(StringRef cls, StringRef cat,
149
28
                       StringRef clsExt, StringRef catExt) {
150
28
    generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
151
28
  }
152
153
  /// Generate a USR fragment for an Objective-C property.
154
177
  void GenObjCProperty(StringRef prop, bool isClassProp) {
155
177
    generateUSRForObjCProperty(prop, isClassProp, Out);
156
177
  }
157
158
  /// Generate a USR for an Objective-C protocol.
159
86
  void GenObjCProtocol(StringRef prot, StringRef ext) {
160
86
    generateUSRForObjCProtocol(prot, Out, ext);
161
86
  }
162
163
  void VisitType(QualType T);
164
  void VisitTemplateParameterList(const TemplateParameterList *Params);
165
  void VisitTemplateName(TemplateName Name);
166
  void VisitTemplateArgument(const TemplateArgument &Arg);
167
168
  /// Emit a Decl's name using NamedDecl::printName() and return true if
169
  ///  the decl had no name.
170
  bool EmitDeclName(const NamedDecl *D);
171
};
172
} // end anonymous namespace
173
174
//===----------------------------------------------------------------------===//
175
// Generating USRs from ASTS.
176
//===----------------------------------------------------------------------===//
177
178
14.6k
bool USRGenerator::EmitDeclName(const NamedDecl *D) {
179
14.6k
  const unsigned startSize = Buf.size();
180
14.6k
  D->printName(Out);
181
14.6k
  const unsigned endSize = Buf.size();
182
14.6k
  return startSize == endSize;
183
14.6k
}
184
185
22.3k
bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
186
22.3k
  if (D->isExternallyVisible())
187
20.7k
    return false;
188
1.54k
  if (D->getParentFunctionOrMethod())
189
1.04k
    return true;
190
500
  SourceLocation Loc = D->getLocation();
191
500
  if (Loc.isInvalid())
192
0
    return false;
193
500
  const SourceManager &SM = Context->getSourceManager();
194
500
  return !SM.isInSystemHeader(Loc);
195
500
}
196
197
32.1k
void USRGenerator::VisitDeclContext(const DeclContext *DC) {
198
32.1k
  if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
199
14.7k
    Visit(D);
200
17.3k
  else if (isa<LinkageSpecDecl>(DC)) // Linkage specs are transparent in USRs.
201
9
    VisitDeclContext(DC->getParent());
202
32.1k
}
203
204
509
void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
205
509
  // The USR for an ivar declared in a class extension is based on the
206
509
  // ObjCInterfaceDecl, not the ObjCCategoryDecl.
207
509
  if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
208
60
    Visit(ID);
209
449
  else
210
449
    VisitDeclContext(D->getDeclContext());
211
509
  Out << (isa<ObjCIvarDecl>(D) ? 
"@"60
:
"@FI@"449
);
212
509
  if (EmitDeclName(D)) {
213
0
    // Bit fields can be anonymous.
214
0
    IgnoreResults = true;
215
0
    return;
216
0
  }
217
509
}
218
219
8.50k
void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
220
8.50k
  if (ShouldGenerateLocation(D) && 
GenLoc(D, /*IncludeOffset=*/isLocal(D))33
)
221
0
    return;
222
8.50k
223
8.50k
  const unsigned StartSize = Buf.size();
224
8.50k
  VisitDeclContext(D->getDeclContext());
225
8.50k
  if (Buf.size() == StartSize)
226
3.58k
    GenExtSymbolContainer(D);
227
8.50k
228
8.50k
  bool IsTemplate = false;
229
8.50k
  if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
230
398
    IsTemplate = true;
231
398
    Out << "@FT@";
232
398
    VisitTemplateParameterList(FunTmpl->getTemplateParameters());
233
398
  } else
234
8.10k
    Out << "@F@";
235
8.50k
236
8.50k
  PrintingPolicy Policy(Context->getLangOpts());
237
8.50k
  // Forward references can have different template argument names. Suppress the
238
8.50k
  // template argument names in constructors to make their USR more stable.
239
8.50k
  Policy.SuppressTemplateArgsInCXXConstructors = true;
240
8.50k
  D->getDeclName().print(Out, Policy);
241
8.50k
242
8.50k
  ASTContext &Ctx = *Context;
243
8.50k
  if ((!Ctx.getLangOpts().CPlusPlus || 
D->isExternC()8.20k
) &&
244
8.50k
      
!D->hasAttr<OverloadableAttr>()310
)
245
306
    return;
246
8.19k
247
8.19k
  if (const TemplateArgumentList *
248
8.19k
        SpecArgs = D->getTemplateSpecializationArgs()) {
249
35
    Out << '<';
250
98
    for (unsigned I = 0, N = SpecArgs->size(); I != N; 
++I63
) {
251
63
      Out << '#';
252
63
      VisitTemplateArgument(SpecArgs->get(I));
253
63
    }
254
35
    Out << '>';
255
35
  }
256
8.19k
257
8.19k
  // Mangle in type information for the arguments.
258
8.19k
  for (auto PD : D->parameters()) {
259
2.11k
    Out << '#';
260
2.11k
    VisitType(PD->getType());
261
2.11k
  }
262
8.19k
  if (D->isVariadic())
263
8
    Out << '.';
264
8.19k
  if (IsTemplate) {
265
397
    // Function templates can be overloaded by return type, for example:
266
397
    // \code
267
397
    //   template <class T> typename T::A foo() {}
268
397
    //   template <class T> typename T::B foo() {}
269
397
    // \endcode
270
397
    Out << '#';
271
397
    VisitType(D->getReturnType());
272
397
  }
273
8.19k
  Out << '#';
274
8.19k
  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
275
4.62k
    if (MD->isStatic())
276
779
      Out << 'S';
277
4.62k
    // FIXME: OpenCL: Need to consider address spaces
278
4.62k
    if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
279
137
      Out << (char)('0' + quals);
280
4.62k
    switch (MD->getRefQualifier()) {
281
4.62k
    
case RQ_None: break4.61k
;
282
4.62k
    
case RQ_LValue: Out << '&'; break1
;
283
4.62k
    
case RQ_RValue: Out << "&&"; break1
;
284
4.62k
    }
285
4.62k
  }
286
8.19k
}
287
288
1.09k
void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
289
1.09k
  VisitDeclContext(D->getDeclContext());
290
1.09k
  Out << "@";
291
1.09k
292
1.09k
  if (EmitDeclName(D)) {
293
0
    // The string can be empty if the declaration has no name; e.g., it is
294
0
    // the ParmDecl with no name for declaration of a function pointer type,
295
0
    // e.g.: void  (*f)(void *);
296
0
    // In this case, don't generate a USR.
297
0
    IgnoreResults = true;
298
0
  }
299
1.09k
}
300
301
1.74k
void USRGenerator::VisitVarDecl(const VarDecl *D) {
302
1.74k
  // VarDecls can be declared 'extern' within a function or method body,
303
1.74k
  // but their enclosing DeclContext is the function, not the TU.  We need
304
1.74k
  // to check the storage class to correctly generate the USR.
305
1.74k
  if (ShouldGenerateLocation(D) && 
GenLoc(D, /*IncludeOffset=*/isLocal(D))1.03k
)
306
0
    return;
307
1.74k
308
1.74k
  VisitDeclContext(D->getDeclContext());
309
1.74k
310
1.74k
  if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
311
10
    Out << "@VT";
312
10
    VisitTemplateParameterList(VarTmpl->getTemplateParameters());
313
1.73k
  } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
314
0
             = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
315
0
    Out << "@VP";
316
0
    VisitTemplateParameterList(PartialSpec->getTemplateParameters());
317
0
  }
318
1.74k
319
1.74k
  // Variables always have simple names.
320
1.74k
  StringRef s = D->getName();
321
1.74k
322
1.74k
  // The string can be empty if the declaration has no name; e.g., it is
323
1.74k
  // the ParmDecl with no name for declaration of a function pointer type, e.g.:
324
1.74k
  //    void  (*f)(void *);
325
1.74k
  // In this case, don't generate a USR.
326
1.74k
  if (s.empty())
327
69
    IgnoreResults = true;
328
1.67k
  else
329
1.67k
    Out << '@' << s;
330
1.74k
331
1.74k
  // For a template specialization, mangle the template arguments.
332
1.74k
  if (const VarTemplateSpecializationDecl *Spec
333
4
                              = dyn_cast<VarTemplateSpecializationDecl>(D)) {
334
4
    const TemplateArgumentList &Args = Spec->getTemplateArgs();
335
4
    Out << '>';
336
8
    for (unsigned I = 0, N = Args.size(); I != N; 
++I4
) {
337
4
      Out << '#';
338
4
      VisitTemplateArgument(Args.get(I));
339
4
    }
340
4
  }
341
1.74k
}
342
343
12
void USRGenerator::VisitBindingDecl(const BindingDecl *D) {
344
12
  if (isLocal(D) && 
GenLoc(D, /*IncludeOffset=*/true)2
)
345
0
    return;
346
12
  VisitNamedDecl(D);
347
12
}
348
349
void USRGenerator::VisitNonTypeTemplateParmDecl(
350
18
                                        const NonTypeTemplateParmDecl *D) {
351
18
  GenLoc(D, /*IncludeOffset=*/true);
352
18
}
353
354
void USRGenerator::VisitTemplateTemplateParmDecl(
355
2
                                        const TemplateTemplateParmDecl *D) {
356
2
  GenLoc(D, /*IncludeOffset=*/true);
357
2
}
358
359
7.25k
void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
360
7.25k
  if (D->isAnonymousNamespace()) {
361
14
    Out << "@aN";
362
14
    return;
363
14
  }
364
7.23k
365
7.23k
  VisitDeclContext(D->getDeclContext());
366
7.23k
  if (!IgnoreResults)
367
7.23k
    Out << "@N@" << D->getName();
368
7.23k
}
369
370
178
void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
371
178
  VisitFunctionDecl(D->getTemplatedDecl());
372
178
}
373
374
664
void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
375
664
  VisitTagDecl(D->getTemplatedDecl());
376
664
}
377
378
19
void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
379
19
  VisitDeclContext(D->getDeclContext());
380
19
  if (!IgnoreResults)
381
19
    Out << "@NA@" << D->getName();
382
19
}
383
384
362
void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
385
362
  const DeclContext *container = D->getDeclContext();
386
362
  if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
387
8
    Visit(pd);
388
8
  }
389
354
  else {
390
354
    // The USR for a method declared in a class extension or category is based on
391
354
    // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
392
354
    const ObjCInterfaceDecl *ID = D->getClassInterface();
393
354
    if (!ID) {
394
1
      IgnoreResults = true;
395
1
      return;
396
1
    }
397
353
    auto getCategoryContext = [](const ObjCMethodDecl *D) ->
398
353
                                    const ObjCCategoryDecl * {
399
353
      if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
400
26
        return CD;
401
327
      if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
402
6
        return ICD->getCategoryDecl();
403
321
      return nullptr;
404
321
    };
405
353
    auto *CD = getCategoryContext(D);
406
353
    VisitObjCContainerDecl(ID, CD);
407
353
  }
408
362
  // Ideally we would use 'GenObjCMethod', but this is such a hot path
409
362
  // for Objective-C code that we don't want to use
410
362
  // DeclarationName::getAsString().
411
362
  
Out << (D->isInstanceMethod() 361
?
"(im)"310
:
"(cm)"51
)
412
361
      << DeclarationName(D->getSelector());
413
361
}
414
415
void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
416
1.25k
                                          const ObjCCategoryDecl *CatD) {
417
1.25k
  switch (D->getKind()) {
418
1.25k
    default:
419
0
      llvm_unreachable("Invalid ObjC container.");
420
1.25k
    case Decl::ObjCInterface:
421
1.13k
    case Decl::ObjCImplementation:
422
1.13k
      GenObjCClass(D->getName(), GetExternalSourceContainer(D),
423
1.13k
                   GetExternalSourceContainer(CatD));
424
1.13k
      break;
425
1.13k
    case Decl::ObjCCategory: {
426
26
      const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
427
26
      const ObjCInterfaceDecl *ID = CD->getClassInterface();
428
26
      if (!ID) {
429
1
        // Handle invalid code where the @interface might not
430
1
        // have been specified.
431
1
        // FIXME: We should be able to generate this USR even if the
432
1
        // @interface isn't available.
433
1
        IgnoreResults = true;
434
1
        return;
435
1
      }
436
25
      // Specially handle class extensions, which are anonymous categories.
437
25
      // We want to mangle in the location to uniquely distinguish them.
438
25
      if (CD->IsClassExtension()) {
439
6
        Out << "objc(ext)" << ID->getName() << '@';
440
6
        GenLoc(CD, /*IncludeOffset=*/true);
441
6
      }
442
19
      else
443
19
        GenObjCCategory(ID->getName(), CD->getName(),
444
19
                        GetExternalSourceContainer(ID),
445
19
                        GetExternalSourceContainer(CD));
446
25
447
25
      break;
448
25
    }
449
25
    case Decl::ObjCCategoryImpl: {
450
9
      const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
451
9
      const ObjCInterfaceDecl *ID = CD->getClassInterface();
452
9
      if (!ID) {
453
0
        // Handle invalid code where the @interface might not
454
0
        // have been specified.
455
0
        // FIXME: We should be able to generate this USR even if the
456
0
        // @interface isn't available.
457
0
        IgnoreResults = true;
458
0
        return;
459
0
      }
460
9
      GenObjCCategory(ID->getName(), CD->getName(),
461
9
                      GetExternalSourceContainer(ID),
462
9
                      GetExternalSourceContainer(CD));
463
9
      break;
464
9
    }
465
86
    case Decl::ObjCProtocol: {
466
86
      const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
467
86
      GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
468
86
      break;
469
9
    }
470
1.25k
  }
471
1.25k
}
472
473
177
void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
474
177
  // The USR for a property declared in a class extension or category is based
475
177
  // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
476
177
  if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
477
174
    Visit(ID);
478
3
  else
479
3
    Visit(cast<Decl>(D->getDeclContext()));
480
177
  GenObjCProperty(D->getName(), D->isClassProperty());
481
177
}
482
483
1
void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
484
1
  if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
485
1
    VisitObjCPropertyDecl(PD);
486
1
    return;
487
1
  }
488
0
489
0
  IgnoreResults = true;
490
0
}
491
492
13.0k
void USRGenerator::VisitTagDecl(const TagDecl *D) {
493
13.0k
  // Add the location of the tag decl to handle resolution across
494
13.0k
  // translation units.
495
13.0k
  if (!isa<EnumDecl>(D) &&
496
13.0k
      
ShouldGenerateLocation(D)11.6k
&&
GenLoc(D, /*IncludeOffset=*/isLocal(D))47
)
497
0
    return;
498
13.0k
499
13.0k
  GenExtSymbolContainer(D);
500
13.0k
501
13.0k
  D = D->getCanonicalDecl();
502
13.0k
  VisitDeclContext(D->getDeclContext());
503
13.0k
504
13.0k
  bool AlreadyStarted = false;
505
13.0k
  if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
506
11.5k
    if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
507
2.28k
      AlreadyStarted = true;
508
2.28k
509
2.28k
      switch (D->getTagKind()) {
510
2.28k
      case TTK_Interface:
511
2.28k
      case TTK_Class:
512
2.28k
      case TTK_Struct: Out << "@ST"; break;
513
2.28k
      
case TTK_Union: Out << "@UT"; break0
;
514
2.28k
      
case TTK_Enum: 0
llvm_unreachable0
("enum template");
515
2.28k
      }
516
2.28k
      VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
517
9.29k
    } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
518
41
                = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
519
41
      AlreadyStarted = true;
520
41
521
41
      switch (D->getTagKind()) {
522
41
      case TTK_Interface:
523
41
      case TTK_Class:
524
41
      case TTK_Struct: Out << "@SP"; break;
525
41
      
case TTK_Union: Out << "@UP"; break0
;
526
41
      
case TTK_Enum: 0
llvm_unreachable0
("enum partial specialization");
527
41
      }
528
41
      VisitTemplateParameterList(PartialSpec->getTemplateParameters());
529
41
    }
530
11.5k
  }
531
13.0k
532
13.0k
  if (!AlreadyStarted) {
533
10.7k
    switch (D->getTagKind()) {
534
10.7k
      case TTK_Interface:
535
9.30k
      case TTK_Class:
536
9.30k
      case TTK_Struct: Out << "@S"; break;
537
9.30k
      
case TTK_Union: Out << "@U"; break10
;
538
9.30k
      
case TTK_Enum: Out << "@E"; break1.40k
;
539
13.0k
    }
540
13.0k
  }
541
13.0k
542
13.0k
  Out << '@';
543
13.0k
  assert(Buf.size() > 0);
544
13.0k
  const unsigned off = Buf.size() - 1;
545
13.0k
546
13.0k
  if (EmitDeclName(D)) {
547
102
    if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
548
22
      Buf[off] = 'A';
549
22
      Out << '@' << *TD;
550
22
    }
551
80
  else {
552
80
    if (D->isEmbeddedInDeclarator() && 
!D->isFreeStanding()34
) {
553
32
      printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
554
48
    } else {
555
48
      Buf[off] = 'a';
556
48
      if (auto *ED = dyn_cast<EnumDecl>(D)) {
557
28
        // Distinguish USRs of anonymous enums by using their first enumerator.
558
28
        auto enum_range = ED->enumerators();
559
28
        if (enum_range.begin() != enum_range.end()) {
560
28
          Out << '@' << **enum_range.begin();
561
28
        }
562
28
      }
563
48
    }
564
80
  }
565
102
  }
566
13.0k
567
13.0k
  // For a class template specialization, mangle the template arguments.
568
13.0k
  if (const ClassTemplateSpecializationDecl *Spec
569
617
                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
570
617
    const TemplateArgumentList &Args = Spec->getTemplateArgs();
571
617
    Out << '>';
572
1.40k
    for (unsigned I = 0, N = Args.size(); I != N; 
++I783
) {
573
783
      Out << '#';
574
783
      VisitTemplateArgument(Args.get(I));
575
783
    }
576
617
  }
577
13.0k
}
578
579
418
void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
580
418
  if (ShouldGenerateLocation(D) && 
GenLoc(D, /*IncludeOffset=*/isLocal(D))417
)
581
0
    return;
582
418
  const DeclContext *DC = D->getDeclContext();
583
418
  if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
584
305
    Visit(DCN);
585
418
  Out << "@T@";
586
418
  Out << D->getName();
587
418
}
588
589
580
void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
590
580
  GenLoc(D, /*IncludeOffset=*/true);
591
580
}
592
593
16.6k
void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
594
16.6k
  StringRef Container = GetExternalSourceContainer(D);
595
16.6k
  if (!Container.empty())
596
2
    Out << "@M@" << Container;
597
16.6k
}
598
599
2.15k
bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
600
2.15k
  if (generatedLoc)
601
12
    return IgnoreResults;
602
2.14k
  generatedLoc = true;
603
2.14k
604
2.14k
  // Guard against null declarations in invalid code.
605
2.14k
  if (!D) {
606
0
    IgnoreResults = true;
607
0
    return true;
608
0
  }
609
2.14k
610
2.14k
  // Use the location of canonical decl.
611
2.14k
  D = D->getCanonicalDecl();
612
2.14k
613
2.14k
  IgnoreResults =
614
2.14k
      IgnoreResults || printLoc(Out, D->getBeginLoc(),
615
2.14k
                                Context->getSourceManager(), IncludeOffset);
616
2.14k
617
2.14k
  return IgnoreResults;
618
2.14k
}
619
620
13
static void printQualifier(llvm::raw_ostream &Out, ASTContext &Ctx, NestedNameSpecifier *NNS) {
621
13
  // FIXME: Encode the qualifier, don't just print it.
622
13
  PrintingPolicy PO(Ctx.getLangOpts());
623
13
  PO.SuppressTagKeyword = true;
624
13
  PO.SuppressUnwrittenScope = true;
625
13
  PO.ConstantArraySizeAsWritten = false;
626
13
  PO.AnonymousTagLocations = false;
627
13
  NNS->print(Out, PO);
628
13
}
629
630
3.63k
void USRGenerator::VisitType(QualType T) {
631
3.63k
  // This method mangles in USR information for types.  It can possibly
632
3.63k
  // just reuse the naming-mangling logic used by codegen, although the
633
3.63k
  // requirements for USRs might not be the same.
634
3.63k
  ASTContext &Ctx = *Context;
635
3.63k
636
4.40k
  do {
637
4.40k
    T = Ctx.getCanonicalType(T);
638
4.40k
    Qualifiers Q = T.getQualifiers();
639
4.40k
    unsigned qVal = 0;
640
4.40k
    if (Q.hasConst())
641
342
      qVal |= 0x1;
642
4.40k
    if (Q.hasVolatile())
643
0
      qVal |= 0x2;
644
4.40k
    if (Q.hasRestrict())
645
0
      qVal |= 0x4;
646
4.40k
    if(qVal)
647
342
      Out << ((char) ('0' + qVal));
648
4.40k
649
4.40k
    // Mangle in ObjC GC qualifiers?
650
4.40k
651
4.40k
    if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
652
9
      Out << 'P';
653
9
      T = Expansion->getPattern();
654
9
    }
655
4.40k
656
4.40k
    if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
657
2.15k
      unsigned char c = '\0';
658
2.15k
      switch (BT->getKind()) {
659
2.15k
        case BuiltinType::Void:
660
385
          c = 'v'; break;
661
2.15k
        case BuiltinType::Bool:
662
81
          c = 'b'; break;
663
2.15k
        case BuiltinType::UChar:
664
2
          c = 'c'; break;
665
2.15k
        case BuiltinType::Char8:
666
0
          c = 'u'; break; // FIXME: Check this doesn't collide
667
2.15k
        case BuiltinType::Char16:
668
0
          c = 'q'; break;
669
2.15k
        case BuiltinType::Char32:
670
0
          c = 'w'; break;
671
2.15k
        case BuiltinType::UShort:
672
0
          c = 's'; break;
673
2.15k
        case BuiltinType::UInt:
674
6
          c = 'i'; break;
675
2.15k
        case BuiltinType::ULong:
676
4
          c = 'l'; break;
677
2.15k
        case BuiltinType::ULongLong:
678
4
          c = 'k'; break;
679
2.15k
        case BuiltinType::UInt128:
680
0
          c = 'j'; break;
681
2.15k
        case BuiltinType::Char_U:
682
47
        case BuiltinType::Char_S:
683
47
          c = 'C'; break;
684
47
        case BuiltinType::SChar:
685
2
          c = 'r'; break;
686
47
        case BuiltinType::WChar_S:
687
0
        case BuiltinType::WChar_U:
688
0
          c = 'W'; break;
689
0
        case BuiltinType::Short:
690
0
          c = 'S'; break;
691
1.46k
        case BuiltinType::Int:
692
1.46k
          c = 'I'; break;
693
1
        case BuiltinType::Long:
694
1
          c = 'L'; break;
695
0
        case BuiltinType::LongLong:
696
0
          c = 'K'; break;
697
0
        case BuiltinType::Int128:
698
0
          c = 'J'; break;
699
0
        case BuiltinType::Float16:
700
0
        case BuiltinType::Half:
701
0
          c = 'h'; break;
702
62
        case BuiltinType::Float:
703
62
          c = 'f'; break;
704
99
        case BuiltinType::Double:
705
99
          c = 'd'; break;
706
0
        case BuiltinType::LongDouble:
707
0
          c = 'D'; break;
708
0
        case BuiltinType::Float128:
709
0
          c = 'Q'; break;
710
0
        case BuiltinType::NullPtr:
711
0
          c = 'n'; break;
712
0
#define BUILTIN_TYPE(Id, SingletonId)
713
0
#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
714
0
#include "clang/AST/BuiltinTypes.def"
715
0
        case BuiltinType::Dependent:
716
0
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
717
0
        case BuiltinType::Id:
718
0
#include "clang/Basic/OpenCLImageTypes.def"
719
0
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
720
0
        case BuiltinType::Id:
721
0
#include "clang/Basic/OpenCLExtensionTypes.def"
722
0
        case BuiltinType::OCLEvent:
723
0
        case BuiltinType::OCLClkEvent:
724
0
        case BuiltinType::OCLQueue:
725
0
        case BuiltinType::OCLReserveID:
726
0
        case BuiltinType::OCLSampler:
727
0
        case BuiltinType::ShortAccum:
728
0
        case BuiltinType::Accum:
729
0
        case BuiltinType::LongAccum:
730
0
        case BuiltinType::UShortAccum:
731
0
        case BuiltinType::UAccum:
732
0
        case BuiltinType::ULongAccum:
733
0
        case BuiltinType::ShortFract:
734
0
        case BuiltinType::Fract:
735
0
        case BuiltinType::LongFract:
736
0
        case BuiltinType::UShortFract:
737
0
        case BuiltinType::UFract:
738
0
        case BuiltinType::ULongFract:
739
0
        case BuiltinType::SatShortAccum:
740
0
        case BuiltinType::SatAccum:
741
0
        case BuiltinType::SatLongAccum:
742
0
        case BuiltinType::SatUShortAccum:
743
0
        case BuiltinType::SatUAccum:
744
0
        case BuiltinType::SatULongAccum:
745
0
        case BuiltinType::SatShortFract:
746
0
        case BuiltinType::SatFract:
747
0
        case BuiltinType::SatLongFract:
748
0
        case BuiltinType::SatUShortFract:
749
0
        case BuiltinType::SatUFract:
750
0
        case BuiltinType::SatULongFract:
751
0
          IgnoreResults = true;
752
0
          return;
753
3
        case BuiltinType::ObjCId:
754
3
          c = 'o'; break;
755
0
        case BuiltinType::ObjCClass:
756
0
          c = 'O'; break;
757
0
        case BuiltinType::ObjCSel:
758
0
          c = 'e'; break;
759
2.15k
      }
760
2.15k
      Out << c;
761
2.15k
      return;
762
2.15k
    }
763
2.24k
764
2.24k
    // If we have already seen this (non-built-in) type, use a substitution
765
2.24k
    // encoding.
766
2.24k
    llvm::DenseMap<const Type *, unsigned>::iterator Substitution
767
2.24k
      = TypeSubstitutions.find(T.getTypePtr());
768
2.24k
    if (Substitution != TypeSubstitutions.end()) {
769
174
      Out << 'S' << Substitution->second << '_';
770
174
      return;
771
2.07k
    } else {
772
2.07k
      // Record this as a substitution.
773
2.07k
      unsigned Number = TypeSubstitutions.size();
774
2.07k
      TypeSubstitutions[T.getTypePtr()] = Number;
775
2.07k
    }
776
2.24k
777
2.24k
    
if (const PointerType *2.07k
PT2.07k
= T->getAs<PointerType>()) {
778
222
      Out << '*';
779
222
      T = PT->getPointeeType();
780
222
      continue;
781
222
    }
782
1.85k
    if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
783
5
      Out << '*';
784
5
      T = OPT->getPointeeType();
785
5
      continue;
786
5
    }
787
1.84k
    if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
788
80
      Out << "&&";
789
80
      T = RT->getPointeeType();
790
80
      continue;
791
80
    }
792
1.76k
    if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
793
458
      Out << '&';
794
458
      T = RT->getPointeeType();
795
458
      continue;
796
458
    }
797
1.30k
    if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
798
60
      Out << 'F';
799
60
      VisitType(FT->getReturnType());
800
60
      Out << '(';
801
60
      for (const auto &I : FT->param_types()) {
802
43
        Out << '#';
803
43
        VisitType(I);
804
43
      }
805
60
      Out << ')';
806
60
      if (FT->isVariadic())
807
0
        Out << '.';
808
60
      return;
809
60
    }
810
1.24k
    if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
811
0
      Out << 'B';
812
0
      T = BT->getPointeeType();
813
0
      continue;
814
0
    }
815
1.24k
    if (const ComplexType *CT = T->getAs<ComplexType>()) {
816
0
      Out << '<';
817
0
      T = CT->getElementType();
818
0
      continue;
819
0
    }
820
1.24k
    if (const TagType *TT = T->getAs<TagType>()) {
821
531
      Out << '$';
822
531
      VisitTagDecl(TT->getDecl());
823
531
      return;
824
531
    }
825
717
    if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
826
2
      Out << '$';
827
2
      VisitObjCInterfaceDecl(OIT->getDecl());
828
2
      return;
829
2
    }
830
715
    if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
831
3
      Out << 'Q';
832
3
      VisitType(OIT->getBaseType());
833
3
      for (auto *Prot : OIT->getProtocols())
834
6
        VisitObjCProtocolDecl(Prot);
835
3
      return;
836
3
    }
837
712
    if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
838
645
      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
839
645
      return;
840
645
    }
841
67
    if (const TemplateSpecializationType *Spec
842
54
                                    = T->getAs<TemplateSpecializationType>()) {
843
54
      Out << '>';
844
54
      VisitTemplateName(Spec->getTemplateName());
845
54
      Out << Spec->getNumArgs();
846
148
      for (unsigned I = 0, N = Spec->getNumArgs(); I != N; 
++I94
)
847
94
        VisitTemplateArgument(Spec->getArg(I));
848
54
      return;
849
54
    }
850
13
    if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
851
2
      Out << '^';
852
2
      printQualifier(Out, Ctx, DNT->getQualifier());
853
2
      Out << ':' << DNT->getIdentifier()->getName();
854
2
      return;
855
2
    }
856
11
    if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) {
857
4
      T = InjT->getInjectedSpecializationType();
858
4
      continue;
859
4
    }
860
7
    if (const auto *VT = T->getAs<VectorType>()) {
861
4
      Out << (T->isExtVectorType() ? 
']'2
:
'['2
);
862
4
      Out << VT->getNumElements();
863
4
      T = VT->getElementType();
864
4
      continue;
865
4
    }
866
3
    if (const auto *const AT = dyn_cast<ArrayType>(T)) {
867
3
      Out << '{';
868
3
      switch (AT->getSizeModifier()) {
869
3
      case ArrayType::Static:
870
0
        Out << 's';
871
0
        break;
872
3
      case ArrayType::Star:
873
0
        Out << '*';
874
0
        break;
875
3
      case ArrayType::Normal:
876
3
        Out << 'n';
877
3
        break;
878
3
      }
879
3
      if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
880
3
        Out << CAT->getSize();
881
3
882
3
      T = AT->getElementType();
883
3
      continue;
884
3
    }
885
0
886
0
    // Unhandled type.
887
0
    Out << ' ';
888
0
    break;
889
776
  } while (true);
890
3.63k
}
891
892
void USRGenerator::VisitTemplateParameterList(
893
2.80k
                                         const TemplateParameterList *Params) {
894
2.80k
  if (!Params)
895
0
    return;
896
2.80k
  Out << '>' << Params->size();
897
2.80k
  for (TemplateParameterList::const_iterator P = Params->begin(),
898
2.80k
                                          PEnd = Params->end();
899
6.10k
       P != PEnd; 
++P3.30k
) {
900
3.30k
    Out << '#';
901
3.30k
    if (isa<TemplateTypeParmDecl>(*P)) {
902
3.17k
      if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
903
38
        Out<< 'p';
904
3.17k
      Out << 'T';
905
3.17k
      continue;
906
3.17k
    }
907
133
908
133
    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
909
69
      if (NTTP->isParameterPack())
910
0
        Out << 'p';
911
69
      Out << 'N';
912
69
      VisitType(NTTP->getType());
913
69
      continue;
914
69
    }
915
64
916
64
    TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
917
64
    if (TTP->isParameterPack())
918
0
      Out << 'p';
919
64
    Out << 't';
920
64
    VisitTemplateParameterList(TTP->getTemplateParameters());
921
64
  }
922
2.80k
}
923
924
54
void USRGenerator::VisitTemplateName(TemplateName Name) {
925
54
  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
926
54
    if (TemplateTemplateParmDecl *TTP
927
3
                              = dyn_cast<TemplateTemplateParmDecl>(Template)) {
928
3
      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
929
3
      return;
930
3
    }
931
51
932
51
    Visit(Template);
933
51
    return;
934
51
  }
935
54
936
54
  // FIXME: Visit dependent template names.
937
54
}
938
939
950
void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
940
950
  switch (Arg.getKind()) {
941
950
  case TemplateArgument::Null:
942
0
    break;
943
950
944
950
  case TemplateArgument::Declaration:
945
2
    Visit(Arg.getAsDecl());
946
2
    break;
947
950
948
950
  case TemplateArgument::NullPtr:
949
0
    break;
950
950
951
950
  case TemplateArgument::TemplateExpansion:
952
0
    Out << 'P'; // pack expansion of...
953
0
    LLVM_FALLTHROUGH;
954
0
  case TemplateArgument::Template:
955
0
    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
956
0
    break;
957
0
958
2
  case TemplateArgument::Expression:
959
2
    // FIXME: Visit expressions.
960
2
    break;
961
0
962
2
  case TemplateArgument::Pack:
963
2
    Out << 'p' << Arg.pack_size();
964
2
    for (const auto &P : Arg.pack_elements())
965
6
      VisitTemplateArgument(P);
966
2
    break;
967
0
968
920
  case TemplateArgument::Type:
969
920
    VisitType(Arg.getAsType());
970
920
    break;
971
0
972
24
  case TemplateArgument::Integral:
973
24
    Out << 'V';
974
24
    VisitType(Arg.getIntegralType());
975
24
    Out << Arg.getAsIntegral();
976
24
    break;
977
950
  }
978
950
}
979
980
8
void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
981
8
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
982
0
    return;
983
8
  VisitDeclContext(D->getDeclContext());
984
8
  Out << "@UUV@";
985
8
  printQualifier(Out, D->getASTContext(), D->getQualifier());
986
8
  EmitDeclName(D);
987
8
}
988
989
3
void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
990
3
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
991
0
    return;
992
3
  VisitDeclContext(D->getDeclContext());
993
3
  Out << "@UUT@";
994
3
  printQualifier(Out, D->getASTContext(), D->getQualifier());
995
3
  Out << D->getName(); // Simple name.
996
3
}
997
998
999
1000
//===----------------------------------------------------------------------===//
1001
// USR generation functions.
1002
//===----------------------------------------------------------------------===//
1003
1004
static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
1005
                                                 StringRef CatSymDefinedIn,
1006
1.16k
                                                 raw_ostream &OS) {
1007
1.16k
  if (ClsSymDefinedIn.empty() && 
CatSymDefinedIn.empty()1.13k
)
1008
1.13k
    return;
1009
24
  if (CatSymDefinedIn.empty()) {
1010
18
    OS << "@M@" << ClsSymDefinedIn << '@';
1011
18
    return;
1012
18
  }
1013
6
  OS << "@CM@" << CatSymDefinedIn << '@';
1014
6
  if (ClsSymDefinedIn != CatSymDefinedIn) {
1015
5
    OS << ClsSymDefinedIn << '@';
1016
5
  }
1017
6
}
1018
1019
void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
1020
                                           StringRef ExtSymDefinedIn,
1021
1.13k
                                  StringRef CategoryContextExtSymbolDefinedIn) {
1022
1.13k
  combineClassAndCategoryExtContainers(ExtSymDefinedIn,
1023
1.13k
                                       CategoryContextExtSymbolDefinedIn, OS);
1024
1.13k
  OS << "objc(cs)" << Cls;
1025
1.13k
}
1026
1027
void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
1028
                                              raw_ostream &OS,
1029
                                              StringRef ClsSymDefinedIn,
1030
29
                                              StringRef CatSymDefinedIn) {
1031
29
  combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
1032
29
  OS << "objc(cy)" << Cls << '@' << Cat;
1033
29
}
1034
1035
1
void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
1036
1
  OS << '@' << Ivar;
1037
1
}
1038
1039
void clang::index::generateUSRForObjCMethod(StringRef Sel,
1040
                                            bool IsInstanceMethod,
1041
2
                                            raw_ostream &OS) {
1042
2
  OS << (IsInstanceMethod ? 
"(im)"1
:
"(cm)"1
) << Sel;
1043
2
}
1044
1045
void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
1046
178
                                              raw_ostream &OS) {
1047
178
  OS << (isClassProp ? 
"(cpy)"11
:
"(py)"167
) << Prop;
1048
178
}
1049
1050
void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
1051
87
                                              StringRef ExtSymDefinedIn) {
1052
87
  if (!ExtSymDefinedIn.empty())
1053
4
    OS << "@M@" << ExtSymDefinedIn << '@';
1054
87
  OS << "objc(pl)" << Prot;
1055
87
}
1056
1057
void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
1058
0
                                            StringRef ExtSymDefinedIn) {
1059
0
  if (!ExtSymDefinedIn.empty())
1060
0
    OS << "@M@" << ExtSymDefinedIn;
1061
0
  OS << "@E@" << EnumName;
1062
0
}
1063
1064
void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
1065
0
                                              raw_ostream &OS) {
1066
0
  OS << '@' << EnumConstantName;
1067
0
}
1068
1069
bool clang::index::generateUSRForDecl(const Decl *D,
1070
18.7k
                                      SmallVectorImpl<char> &Buf) {
1071
18.7k
  if (!D)
1072
0
    return true;
1073
18.7k
  // We don't ignore decls with invalid source locations. Implicit decls, like
1074
18.7k
  // C++'s operator new function, can have invalid locations but it is fine to
1075
18.7k
  // create USRs that can identify them.
1076
18.7k
1077
18.7k
  USRGenerator UG(&D->getASTContext(), Buf);
1078
18.7k
  UG.Visit(D);
1079
18.7k
  return UG.ignoreResults();
1080
18.7k
}
1081
1082
bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD,
1083
                                       const SourceManager &SM,
1084
2.67k
                                       SmallVectorImpl<char> &Buf) {
1085
2.67k
  if (!MD)
1086
0
    return true;
1087
2.67k
  return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1088
2.67k
                             SM, Buf);
1089
2.67k
1090
2.67k
}
1091
1092
bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
1093
                                       const SourceManager &SM,
1094
10.7k
                                       SmallVectorImpl<char> &Buf) {
1095
10.7k
  // Don't generate USRs for things with invalid locations.
1096
10.7k
  if (MacroName.empty() || Loc.isInvalid())
1097
0
    return true;
1098
10.7k
1099
10.7k
  llvm::raw_svector_ostream Out(Buf);
1100
10.7k
1101
10.7k
  // Assume that system headers are sane.  Don't put source location
1102
10.7k
  // information into the USR if the macro comes from a system header.
1103
10.7k
  bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);
1104
10.7k
1105
10.7k
  Out << getUSRSpacePrefix();
1106
10.7k
  if (ShouldGenerateLocation)
1107
432
    printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1108
10.7k
  Out << "@macro@";
1109
10.7k
  Out << MacroName;
1110
10.7k
  return false;
1111
10.7k
}
1112
1113
bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
1114
0
                                      SmallVectorImpl<char> &Buf) {
1115
0
  if (T.isNull())
1116
0
    return true;
1117
0
  T = T.getCanonicalType();
1118
0
1119
0
  USRGenerator UG(&Ctx, Buf);
1120
0
  UG.VisitType(T);
1121
0
  return UG.ignoreResults();
1122
0
}
1123
1124
bool clang::index::generateFullUSRForModule(const Module *Mod,
1125
17
                                            raw_ostream &OS) {
1126
17
  if (!Mod->Parent)
1127
9
    return generateFullUSRForTopLevelModuleName(Mod->Name, OS);
1128
8
  if (generateFullUSRForModule(Mod->Parent, OS))
1129
0
    return true;
1130
8
  return generateUSRFragmentForModule(Mod, OS);
1131
8
}
1132
1133
bool clang::index::generateFullUSRForTopLevelModuleName(StringRef ModName,
1134
9
                                                        raw_ostream &OS) {
1135
9
  OS << getUSRSpacePrefix();
1136
9
  return generateUSRFragmentForModuleName(ModName, OS);
1137
9
}
1138
1139
bool clang::index::generateUSRFragmentForModule(const Module *Mod,
1140
8
                                                raw_ostream &OS) {
1141
8
  return generateUSRFragmentForModuleName(Mod->Name, OS);
1142
8
}
1143
1144
bool clang::index::generateUSRFragmentForModuleName(StringRef ModName,
1145
17
                                                    raw_ostream &OS) {
1146
17
  OS << "@M@" << ModName;
1147
17
  return false;
1148
17
}