1 //===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the generation and use of USRs from CXEntities.
12 //===----------------------------------------------------------------------===//
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/DeclVisitor.h"
19 #include "clang/Frontend/ASTUnit.h"
20 #include "clang/Lex/PreprocessingRecord.h"
21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/Support/raw_ostream.h"
24 using namespace clang
;
25 using namespace clang::cxstring
;
27 //===----------------------------------------------------------------------===//
29 //===----------------------------------------------------------------------===//
32 class USRGenerator
: public DeclVisitor
<USRGenerator
> {
33 llvm::OwningPtr
<llvm::SmallString
<128> > OwnedBuf
;
34 llvm::SmallVectorImpl
<char> &Buf
;
35 llvm::raw_svector_ostream Out
;
40 llvm::DenseMap
<const Type
*, unsigned> TypeSubstitutions
;
43 USRGenerator(const CXCursor
*C
= 0, llvm::SmallVectorImpl
<char> *extBuf
= 0)
44 : OwnedBuf(extBuf
? 0 : new llvm::SmallString
<128>()),
45 Buf(extBuf
? *extBuf
: *OwnedBuf
.get()),
48 AU(C
? cxcursor::getCursorASTUnit(*C
) : 0),
51 // Add the USR space prefix.
55 llvm::StringRef
str() {
59 USRGenerator
* operator->() { return this; }
62 llvm::raw_svector_ostream
&operator<<(const T
&x
) {
67 bool ignoreResults() const { return IgnoreResults
; }
69 // Visitation methods from generating USRs from AST elements.
70 void VisitDeclContext(DeclContext
*D
);
71 void VisitFieldDecl(FieldDecl
*D
);
72 void VisitFunctionDecl(FunctionDecl
*D
);
73 void VisitNamedDecl(NamedDecl
*D
);
74 void VisitNamespaceDecl(NamespaceDecl
*D
);
75 void VisitNamespaceAliasDecl(NamespaceAliasDecl
*D
);
76 void VisitFunctionTemplateDecl(FunctionTemplateDecl
*D
);
77 void VisitClassTemplateDecl(ClassTemplateDecl
*D
);
78 void VisitObjCClassDecl(ObjCClassDecl
*CD
);
79 void VisitObjCContainerDecl(ObjCContainerDecl
*CD
);
80 void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl
*P
);
81 void VisitObjCMethodDecl(ObjCMethodDecl
*MD
);
82 void VisitObjCPropertyDecl(ObjCPropertyDecl
*D
);
83 void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl
*D
);
84 void VisitTagDecl(TagDecl
*D
);
85 void VisitTypedefDecl(TypedefDecl
*D
);
86 void VisitTemplateTypeParmDecl(TemplateTypeParmDecl
*D
);
87 void VisitVarDecl(VarDecl
*D
);
88 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl
*D
);
89 void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl
*D
);
90 void VisitLinkageSpecDecl(LinkageSpecDecl
*D
) {
93 void VisitUsingDirectiveDecl(UsingDirectiveDecl
*D
) {
96 void VisitUsingDecl(UsingDecl
*D
) {
99 void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl
*D
) {
100 IgnoreResults
= true;
102 void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl
*D
) {
103 IgnoreResults
= true;
106 /// Generate the string component containing the location of the
108 bool GenLoc(const Decl
*D
);
110 /// String generation methods used both by the visitation methods
111 /// and from other clients that want to directly generate USRs. These
112 /// methods do not construct complete USRs (which incorporate the parents
113 /// of an AST element), but only the fragments concerning the AST element
116 /// Generate a USR for an Objective-C class.
117 void GenObjCClass(llvm::StringRef cls
);
118 /// Generate a USR for an Objective-C class category.
119 void GenObjCCategory(llvm::StringRef cls
, llvm::StringRef cat
);
120 /// Generate a USR fragment for an Objective-C instance variable. The
121 /// complete USR can be created by concatenating the USR for the
122 /// encompassing class with this USR fragment.
123 void GenObjCIvar(llvm::StringRef ivar
);
124 /// Generate a USR fragment for an Objective-C method.
125 void GenObjCMethod(llvm::StringRef sel
, bool isInstanceMethod
);
126 /// Generate a USR fragment for an Objective-C property.
127 void GenObjCProperty(llvm::StringRef prop
);
128 /// Generate a USR for an Objective-C protocol.
129 void GenObjCProtocol(llvm::StringRef prot
);
131 void VisitType(QualType T
);
132 void VisitTemplateParameterList(const TemplateParameterList
*Params
);
133 void VisitTemplateName(TemplateName Name
);
134 void VisitTemplateArgument(const TemplateArgument
&Arg
);
136 /// Emit a Decl's name using NamedDecl::printName() and return true if
137 /// the decl had no name.
138 bool EmitDeclName(const NamedDecl
*D
);
141 } // end anonymous namespace
143 //===----------------------------------------------------------------------===//
144 // Generating USRs from ASTS.
145 //===----------------------------------------------------------------------===//
147 bool USRGenerator::EmitDeclName(const NamedDecl
*D
) {
149 const unsigned startSize
= Buf
.size();
152 const unsigned endSize
= Buf
.size();
153 return startSize
== endSize
;
156 static bool InAnonymousNamespace(const Decl
*D
) {
157 if (const NamespaceDecl
*ND
= dyn_cast
<NamespaceDecl
>(D
->getDeclContext()))
158 return ND
->isAnonymousNamespace();
162 static inline bool ShouldGenerateLocation(const NamedDecl
*D
) {
163 return D
->getLinkage() != ExternalLinkage
&& !InAnonymousNamespace(D
);
166 void USRGenerator::VisitDeclContext(DeclContext
*DC
) {
167 if (NamedDecl
*D
= dyn_cast
<NamedDecl
>(DC
))
171 void USRGenerator::VisitFieldDecl(FieldDecl
*D
) {
172 VisitDeclContext(D
->getDeclContext());
173 Out
<< (isa
<ObjCIvarDecl
>(D
) ? "@" : "@FI@");
174 if (EmitDeclName(D
)) {
175 // Bit fields can be anonymous.
176 IgnoreResults
= true;
181 void USRGenerator::VisitFunctionDecl(FunctionDecl
*D
) {
182 if (ShouldGenerateLocation(D
) && GenLoc(D
))
185 VisitDeclContext(D
->getDeclContext());
186 if (FunctionTemplateDecl
*FunTmpl
= D
->getDescribedFunctionTemplate()) {
188 VisitTemplateParameterList(FunTmpl
->getTemplateParameters());
193 ASTContext
&Ctx
= AU
->getASTContext();
194 if (!Ctx
.getLangOptions().CPlusPlus
|| D
->isExternC())
197 // Mangle in type information for the arguments.
198 for (FunctionDecl::param_iterator I
= D
->param_begin(), E
= D
->param_end();
201 if (ParmVarDecl
*PD
= *I
)
202 VisitType(PD
->getType());
207 if (CXXMethodDecl
*MD
= dyn_cast
<CXXMethodDecl
>(D
)) {
210 if (unsigned quals
= MD
->getTypeQualifiers())
211 Out
<< (char)('0' + quals
);
215 void USRGenerator::VisitNamedDecl(NamedDecl
*D
) {
216 VisitDeclContext(D
->getDeclContext());
219 if (EmitDeclName(D
)) {
220 // The string can be empty if the declaration has no name; e.g., it is
221 // the ParmDecl with no name for declaration of a function pointer type,
222 // e.g.: void (*f)(void *);
223 // In this case, don't generate a USR.
224 IgnoreResults
= true;
228 void USRGenerator::VisitVarDecl(VarDecl
*D
) {
229 // VarDecls can be declared 'extern' within a function or method body,
230 // but their enclosing DeclContext is the function, not the TU. We need
231 // to check the storage class to correctly generate the USR.
232 if (ShouldGenerateLocation(D
) && GenLoc(D
))
235 VisitDeclContext(D
->getDeclContext());
237 // Variables always have simple names.
238 llvm::StringRef s
= D
->getName();
240 // The string can be empty if the declaration has no name; e.g., it is
241 // the ParmDecl with no name for declaration of a function pointer type, e.g.:
242 // void (*f)(void *);
243 // In this case, don't generate a USR.
245 IgnoreResults
= true;
250 void USRGenerator::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl
*D
) {
255 void USRGenerator::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl
*D
) {
260 void USRGenerator::VisitNamespaceDecl(NamespaceDecl
*D
) {
261 if (D
->isAnonymousNamespace()) {
266 VisitDeclContext(D
->getDeclContext());
268 Out
<< "@N@" << D
->getName();
271 void USRGenerator::VisitFunctionTemplateDecl(FunctionTemplateDecl
*D
) {
272 VisitFunctionDecl(D
->getTemplatedDecl());
275 void USRGenerator::VisitClassTemplateDecl(ClassTemplateDecl
*D
) {
276 VisitTagDecl(D
->getTemplatedDecl());
279 void USRGenerator::VisitNamespaceAliasDecl(NamespaceAliasDecl
*D
) {
280 VisitDeclContext(D
->getDeclContext());
282 Out
<< "@NA@" << D
->getName();
285 void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl
*D
) {
286 DeclContext
*container
= D
->getDeclContext();
287 if (ObjCProtocolDecl
*pd
= dyn_cast
<ObjCProtocolDecl
>(container
)) {
291 // The USR for a method declared in a class extension or category is based on
292 // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
293 ObjCInterfaceDecl
*ID
= D
->getClassInterface();
295 IgnoreResults
= true;
300 // Ideally we would use 'GenObjCMethod', but this is such a hot path
301 // for Objective-C code that we don't want to use
302 // DeclarationName::getAsString().
303 Out
<< (D
->isInstanceMethod() ? "(im)" : "(cm)");
304 DeclarationName
N(D
->getSelector());
308 void USRGenerator::VisitObjCClassDecl(ObjCClassDecl
*D
) {
309 // FIXME: @class declarations can refer to multiple classes. We need
310 // to be able to traverse these.
311 IgnoreResults
= true;
314 void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl
*D
) {
315 // FIXME: @protocol declarations can refer to multiple protocols. We need
316 // to be able to traverse these.
317 IgnoreResults
= true;
320 void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl
*D
) {
321 switch (D
->getKind()) {
323 assert(false && "Invalid ObjC container.");
324 case Decl::ObjCInterface
:
325 case Decl::ObjCImplementation
:
326 GenObjCClass(D
->getName());
328 case Decl::ObjCCategory
: {
329 ObjCCategoryDecl
*CD
= cast
<ObjCCategoryDecl
>(D
);
330 ObjCInterfaceDecl
*ID
= CD
->getClassInterface();
332 // Handle invalid code where the @interface might not
333 // have been specified.
334 // FIXME: We should be able to generate this USR even if the
335 // @interface isn't available.
336 IgnoreResults
= true;
339 // Specially handle class extensions, which are anonymous categories.
340 // We want to mangle in the location to uniquely distinguish them.
341 if (CD
->IsClassExtension()) {
342 Out
<< "objc(ext)" << ID
->getName() << '@';
346 GenObjCCategory(ID
->getName(), CD
->getName());
350 case Decl::ObjCCategoryImpl
: {
351 ObjCCategoryImplDecl
*CD
= cast
<ObjCCategoryImplDecl
>(D
);
352 ObjCInterfaceDecl
*ID
= CD
->getClassInterface();
354 // Handle invalid code where the @interface might not
355 // have been specified.
356 // FIXME: We should be able to generate this USR even if the
357 // @interface isn't available.
358 IgnoreResults
= true;
361 GenObjCCategory(ID
->getName(), CD
->getName());
364 case Decl::ObjCProtocol
:
365 GenObjCProtocol(cast
<ObjCProtocolDecl
>(D
)->getName());
370 void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl
*D
) {
371 Visit(cast
<Decl
>(D
->getDeclContext()));
372 GenObjCProperty(D
->getName());
375 void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl
*D
) {
376 if (ObjCPropertyDecl
*PD
= D
->getPropertyDecl()) {
377 VisitObjCPropertyDecl(PD
);
381 IgnoreResults
= true;
384 void USRGenerator::VisitTagDecl(TagDecl
*D
) {
385 // Add the location of the tag decl to handle resolution across
386 // translation units.
387 if (ShouldGenerateLocation(D
) && GenLoc(D
))
390 D
= D
->getCanonicalDecl();
391 VisitDeclContext(D
->getDeclContext());
393 bool AlreadyStarted
= false;
394 if (CXXRecordDecl
*CXXRecord
= dyn_cast
<CXXRecordDecl
>(D
)) {
395 if (ClassTemplateDecl
*ClassTmpl
= CXXRecord
->getDescribedClassTemplate()) {
396 AlreadyStarted
= true;
398 switch (D
->getTagKind()) {
399 case TTK_Struct
: Out
<< "@ST"; break;
400 case TTK_Class
: Out
<< "@CT"; break;
401 case TTK_Union
: Out
<< "@UT"; break;
402 case TTK_Enum
: llvm_unreachable("enum template"); break;
404 VisitTemplateParameterList(ClassTmpl
->getTemplateParameters());
405 } else if (ClassTemplatePartialSpecializationDecl
*PartialSpec
406 = dyn_cast
<ClassTemplatePartialSpecializationDecl
>(CXXRecord
)) {
407 AlreadyStarted
= true;
409 switch (D
->getTagKind()) {
410 case TTK_Struct
: Out
<< "@SP"; break;
411 case TTK_Class
: Out
<< "@CP"; break;
412 case TTK_Union
: Out
<< "@UP"; break;
413 case TTK_Enum
: llvm_unreachable("enum partial specialization"); break;
415 VisitTemplateParameterList(PartialSpec
->getTemplateParameters());
419 if (!AlreadyStarted
) {
420 switch (D
->getTagKind()) {
421 case TTK_Struct
: Out
<< "@S"; break;
422 case TTK_Class
: Out
<< "@C"; break;
423 case TTK_Union
: Out
<< "@U"; break;
424 case TTK_Enum
: Out
<< "@E"; break;
430 assert(Buf
.size() > 0);
431 const unsigned off
= Buf
.size() - 1;
433 if (EmitDeclName(D
)) {
434 if (const TypedefDecl
*TD
= D
->getTypedefForAnonDecl()) {
442 // For a class template specialization, mangle the template arguments.
443 if (ClassTemplateSpecializationDecl
*Spec
444 = dyn_cast
<ClassTemplateSpecializationDecl
>(D
)) {
445 const TemplateArgumentList
&Args
= Spec
->getTemplateInstantiationArgs();
447 for (unsigned I
= 0, N
= Args
.size(); I
!= N
; ++I
) {
449 VisitTemplateArgument(Args
.get(I
));
454 void USRGenerator::VisitTypedefDecl(TypedefDecl
*D
) {
455 if (ShouldGenerateLocation(D
) && GenLoc(D
))
457 DeclContext
*DC
= D
->getDeclContext();
458 if (NamedDecl
*DCN
= dyn_cast
<NamedDecl
>(DC
))
464 void USRGenerator::VisitTemplateTypeParmDecl(TemplateTypeParmDecl
*D
) {
469 bool USRGenerator::GenLoc(const Decl
*D
) {
471 return IgnoreResults
;
474 const SourceManager
&SM
= AU
->getSourceManager();
475 SourceLocation L
= D
->getLocStart();
477 IgnoreResults
= true;
480 L
= SM
.getInstantiationLoc(L
);
481 const std::pair
<FileID
, unsigned> &Decomposed
= SM
.getDecomposedLoc(L
);
482 const FileEntry
*FE
= SM
.getFileEntryForID(Decomposed
.first
);
484 Out
<< llvm::sys::path::filename(FE
->getName());
487 // This case really isn't interesting.
488 IgnoreResults
= true;
491 // Use the offest into the FileID to represent the location. Using
492 // a line/column can cause us to look back at the original source file,
493 // which is expensive.
494 Out
<< '@' << Decomposed
.second
;
495 return IgnoreResults
;
498 void USRGenerator::VisitType(QualType T
) {
499 // This method mangles in USR information for types. It can possibly
500 // just reuse the naming-mangling logic used by codegen, although the
501 // requirements for USRs might not be the same.
502 ASTContext
&Ctx
= AU
->getASTContext();
505 T
= Ctx
.getCanonicalType(T
);
506 Qualifiers Q
= T
.getQualifiers();
515 Out
<< ((char) ('0' + qVal
));
517 // Mangle in ObjC GC qualifiers?
519 if (const PackExpansionType
*Expansion
= T
->getAs
<PackExpansionType
>()) {
521 T
= Expansion
->getPattern();
524 if (const BuiltinType
*BT
= T
->getAs
<BuiltinType
>()) {
525 unsigned char c
= '\0';
526 switch (BT
->getKind()) {
527 case BuiltinType::Void
:
529 case BuiltinType::Bool
:
531 case BuiltinType::Char_U
:
532 case BuiltinType::UChar
:
534 case BuiltinType::Char16
:
536 case BuiltinType::Char32
:
538 case BuiltinType::UShort
:
540 case BuiltinType::UInt
:
542 case BuiltinType::ULong
:
544 case BuiltinType::ULongLong
:
546 case BuiltinType::UInt128
:
548 case BuiltinType::Char_S
:
549 case BuiltinType::SChar
:
551 case BuiltinType::WChar_S
:
552 case BuiltinType::WChar_U
:
554 case BuiltinType::Short
:
556 case BuiltinType::Int
:
558 case BuiltinType::Long
:
560 case BuiltinType::LongLong
:
562 case BuiltinType::Int128
:
564 case BuiltinType::Float
:
566 case BuiltinType::Double
:
568 case BuiltinType::LongDouble
:
570 case BuiltinType::NullPtr
:
572 case BuiltinType::Overload
:
573 case BuiltinType::Dependent
:
574 case BuiltinType::UndeducedAuto
:
575 IgnoreResults
= true;
577 case BuiltinType::ObjCId
:
579 case BuiltinType::ObjCClass
:
581 case BuiltinType::ObjCSel
:
588 // If we have already seen this (non-built-in) type, use a substitution
590 llvm::DenseMap
<const Type
*, unsigned>::iterator Substitution
591 = TypeSubstitutions
.find(T
.getTypePtr());
592 if (Substitution
!= TypeSubstitutions
.end()) {
593 Out
<< 'S' << Substitution
->second
<< '_';
596 // Record this as a substitution.
597 unsigned Number
= TypeSubstitutions
.size();
598 TypeSubstitutions
[T
.getTypePtr()] = Number
;
601 if (const PointerType
*PT
= T
->getAs
<PointerType
>()) {
603 T
= PT
->getPointeeType();
606 if (const ReferenceType
*RT
= T
->getAs
<ReferenceType
>()) {
608 T
= RT
->getPointeeType();
611 if (const FunctionProtoType
*FT
= T
->getAs
<FunctionProtoType
>()) {
613 VisitType(FT
->getResultType());
614 for (FunctionProtoType::arg_type_iterator
615 I
= FT
->arg_type_begin(), E
= FT
->arg_type_end(); I
!=E
; ++I
) {
618 if (FT
->isVariadic())
622 if (const BlockPointerType
*BT
= T
->getAs
<BlockPointerType
>()) {
624 T
= BT
->getPointeeType();
627 if (const ComplexType
*CT
= T
->getAs
<ComplexType
>()) {
629 T
= CT
->getElementType();
632 if (const TagType
*TT
= T
->getAs
<TagType
>()) {
634 VisitTagDecl(TT
->getDecl());
637 if (const TemplateTypeParmType
*TTP
= T
->getAs
<TemplateTypeParmType
>()) {
638 Out
<< 't' << TTP
->getDepth() << '.' << TTP
->getIndex();
641 if (const TemplateSpecializationType
*Spec
642 = T
->getAs
<TemplateSpecializationType
>()) {
644 VisitTemplateName(Spec
->getTemplateName());
645 Out
<< Spec
->getNumArgs();
646 for (unsigned I
= 0, N
= Spec
->getNumArgs(); I
!= N
; ++I
)
647 VisitTemplateArgument(Spec
->getArg(I
));
657 void USRGenerator::VisitTemplateParameterList(
658 const TemplateParameterList
*Params
) {
661 Out
<< '>' << Params
->size();
662 for (TemplateParameterList::const_iterator P
= Params
->begin(),
663 PEnd
= Params
->end();
666 if (isa
<TemplateTypeParmDecl
>(*P
)) {
667 if (cast
<TemplateTypeParmDecl
>(*P
)->isParameterPack())
673 if (NonTypeTemplateParmDecl
*NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(*P
)) {
674 if (NTTP
->isParameterPack())
677 VisitType(NTTP
->getType());
681 TemplateTemplateParmDecl
*TTP
= cast
<TemplateTemplateParmDecl
>(*P
);
682 if (TTP
->isParameterPack())
685 VisitTemplateParameterList(TTP
->getTemplateParameters());
689 void USRGenerator::VisitTemplateName(TemplateName Name
) {
690 if (TemplateDecl
*Template
= Name
.getAsTemplateDecl()) {
691 if (TemplateTemplateParmDecl
*TTP
692 = dyn_cast
<TemplateTemplateParmDecl
>(Template
)) {
693 Out
<< 't' << TTP
->getDepth() << '.' << TTP
->getIndex();
701 // FIXME: Visit dependent template names.
704 void USRGenerator::VisitTemplateArgument(const TemplateArgument
&Arg
) {
705 switch (Arg
.getKind()) {
706 case TemplateArgument::Null
:
709 case TemplateArgument::Declaration
:
710 if (Decl
*D
= Arg
.getAsDecl())
714 case TemplateArgument::TemplateExpansion
:
715 Out
<< 'P'; // pack expansion of...
717 case TemplateArgument::Template
:
718 VisitTemplateName(Arg
.getAsTemplateOrTemplatePattern());
721 case TemplateArgument::Expression
:
722 // FIXME: Visit expressions.
725 case TemplateArgument::Pack
:
726 Out
<< 'p' << Arg
.pack_size();
727 for (TemplateArgument::pack_iterator P
= Arg
.pack_begin(), PEnd
= Arg
.pack_end();
729 VisitTemplateArgument(*P
);
732 case TemplateArgument::Type
:
733 VisitType(Arg
.getAsType());
736 case TemplateArgument::Integral
:
738 VisitType(Arg
.getIntegralType());
739 Out
<< *Arg
.getAsIntegral();
744 //===----------------------------------------------------------------------===//
745 // General purpose USR generation methods.
746 //===----------------------------------------------------------------------===//
748 void USRGenerator::GenObjCClass(llvm::StringRef cls
) {
749 Out
<< "objc(cs)" << cls
;
752 void USRGenerator::GenObjCCategory(llvm::StringRef cls
, llvm::StringRef cat
) {
753 Out
<< "objc(cy)" << cls
<< '@' << cat
;
756 void USRGenerator::GenObjCIvar(llvm::StringRef ivar
) {
760 void USRGenerator::GenObjCMethod(llvm::StringRef meth
, bool isInstanceMethod
) {
761 Out
<< (isInstanceMethod
? "(im)" : "(cm)") << meth
;
764 void USRGenerator::GenObjCProperty(llvm::StringRef prop
) {
765 Out
<< "(py)" << prop
;
768 void USRGenerator::GenObjCProtocol(llvm::StringRef prot
) {
769 Out
<< "objc(pl)" << prot
;
772 //===----------------------------------------------------------------------===//
774 //===----------------------------------------------------------------------===//
776 static inline llvm::StringRef
extractUSRSuffix(llvm::StringRef s
) {
777 return s
.startswith("c:") ? s
.substr(2) : "";
780 static CXString
getDeclCursorUSR(const CXCursor
&C
) {
781 Decl
*D
= cxcursor::getCursorDecl(C
);
783 // Don't generate USRs for things with invalid locations.
784 if (!D
|| D
->getLocStart().isInvalid())
785 return createCXString("");
787 // Check if the cursor has 'NoLinkage'.
788 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
))
789 switch (ND
->getLinkage()) {
790 case ExternalLinkage
:
791 // Generate USRs for all entities with external linkage.
794 case UniqueExternalLinkage
:
795 // We allow enums, typedefs, and structs that have no linkage to
796 // have USRs that are anchored to the file they were defined in
797 // (e.g., the header). This is a little gross, but in principal
798 // enums/anonymous structs/etc. defined in a common header file
799 // are referred to across multiple translation units.
800 if (isa
<TagDecl
>(ND
) || isa
<TypedefDecl
>(ND
) ||
801 isa
<EnumConstantDecl
>(ND
) || isa
<FieldDecl
>(ND
) ||
802 isa
<VarDecl
>(ND
) || isa
<NamespaceDecl
>(ND
))
805 case InternalLinkage
:
806 if (isa
<FunctionDecl
>(ND
))
810 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
812 return createCXString("");
814 CXStringBuf
*buf
= cxstring::getCXStringBuf(TU
);
816 return createCXString("");
819 USRGenerator
UG(&C
, &buf
->Data
);
822 if (UG
->ignoreResults()) {
823 disposeCXStringBuf(buf
);
824 return createCXString("");
827 // Return the C-string, but don't make a copy since it is already in
828 // the string buffer.
829 buf
->Data
.push_back('\0');
830 return createCXString(buf
);
835 CXString
clang_getCursorUSR(CXCursor C
) {
836 const CXCursorKind
&K
= clang_getCursorKind(C
);
838 if (clang_isDeclaration(K
))
839 return getDeclCursorUSR(C
);
841 if (K
== CXCursor_MacroDefinition
) {
842 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
844 return createCXString("");
846 CXStringBuf
*buf
= cxstring::getCXStringBuf(TU
);
848 return createCXString("");
851 USRGenerator
UG(&C
, &buf
->Data
);
853 << cxcursor::getCursorMacroDefinition(C
)->getName()->getNameStart();
855 buf
->Data
.push_back('\0');
856 return createCXString(buf
);
859 return createCXString("");
862 CXString
clang_constructUSR_ObjCIvar(const char *name
, CXString classUSR
) {
864 UG
<< extractUSRSuffix(clang_getCString(classUSR
));
865 UG
->GenObjCIvar(name
);
866 return createCXString(UG
.str(), true);
869 CXString
clang_constructUSR_ObjCMethod(const char *name
,
870 unsigned isInstanceMethod
,
873 UG
<< extractUSRSuffix(clang_getCString(classUSR
));
874 UG
->GenObjCMethod(name
, isInstanceMethod
);
875 return createCXString(UG
.str(), true);
878 CXString
clang_constructUSR_ObjCClass(const char *name
) {
880 UG
->GenObjCClass(name
);
881 return createCXString(UG
.str(), true);
884 CXString
clang_constructUSR_ObjCProtocol(const char *name
) {
886 UG
->GenObjCProtocol(name
);
887 return createCXString(UG
.str(), true);
890 CXString
clang_constructUSR_ObjCCategory(const char *class_name
,
891 const char *category_name
) {
893 UG
->GenObjCCategory(class_name
, category_name
);
894 return createCXString(UG
.str(), true);
897 CXString
clang_constructUSR_ObjCProperty(const char *property
,
900 UG
<< extractUSRSuffix(clang_getCString(classUSR
));
901 UG
->GenObjCProperty(property
);
902 return createCXString(UG
.str(), true);