15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/Support/Path.h"
17 #include "llvm/Support/raw_ostream.h"
19 using namespace clang;
20 using namespace clang::index;
36 OS << llvm::sys::path::filename(FE->
getName());
45 OS <<
'@' << Decomposed.second;
53 llvm::raw_svector_ostream Out;
58 llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
72 bool ignoreResults()
const {
return IgnoreResults; }
87 void VisitTagDecl(
const TagDecl *D);
90 void VisitVarDecl(
const VarDecl *D);
100 IgnoreResults =
true;
103 IgnoreResults =
true;
106 IgnoreResults =
true;
109 bool ShouldGenerateLocation(
const NamedDecl *D);
117 bool GenLoc(
const Decl *D,
bool IncludeOffset);
126 void GenObjCClass(StringRef cls) {
130 void GenObjCCategory(StringRef cls, StringRef cat) {
134 void GenObjCProperty(StringRef prop) {
138 void GenObjCProtocol(StringRef prot) {
158 bool USRGenerator::EmitDeclName(
const NamedDecl *D) {
159 const unsigned startSize = Buf.size();
161 const unsigned endSize = Buf.size();
162 return startSize == endSize;
165 bool USRGenerator::ShouldGenerateLocation(
const NamedDecl *D) {
174 void USRGenerator::VisitDeclContext(
const DeclContext *DC) {
175 if (
const NamedDecl *D = dyn_cast<NamedDecl>(DC))
179 void USRGenerator::VisitFieldDecl(
const FieldDecl *D) {
186 Out << (isa<ObjCIvarDecl>(D) ?
"@" :
"@FI@");
187 if (EmitDeclName(D)) {
189 IgnoreResults =
true;
194 void USRGenerator::VisitFunctionDecl(
const FunctionDecl *D) {
195 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
199 bool IsTemplate =
false;
203 VisitTemplateParameterList(FunTmpl->getTemplateParameters());
215 for (
unsigned I = 0, N = SpecArgs->size();
I != N; ++
I) {
217 VisitTemplateArgument(SpecArgs->get(
I));
222 // Mangle in type information for the arguments.
223 for (auto PD : D->params()) {
225 VisitType(PD->getType());
230 // Function templates can be overloaded by return type, for example:
232 // template <class T> typename T::A foo() {}
233 // template <class T> typename T::B foo() {}
236 VisitType(D->getReturnType());
239 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
242 if (unsigned quals = MD->getTypeQualifiers())
243 Out << (char)('0
' + quals);
244 switch (MD->getRefQualifier()) {
246 case RQ_LValue: Out << '&
'; break;
247 case RQ_RValue: Out << "&&"; break;
252 void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
253 VisitDeclContext(D->getDeclContext());
256 if (EmitDeclName(D)) {
257 // The string can be empty if the declaration has no name; e.g., it is
258 // the ParmDecl with no name for declaration of a function pointer type,
259 // e.g.: void (*f)(void *);
260 // In this case, don't generate a USR.
261 IgnoreResults =
true;
265 void USRGenerator::VisitVarDecl(
const VarDecl *D) {
269 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
282 IgnoreResults =
true;
287 void USRGenerator::VisitNonTypeTemplateParmDecl(
293 void USRGenerator::VisitTemplateTemplateParmDecl(
299 void USRGenerator::VisitNamespaceDecl(
const NamespaceDecl *D) {
334 IgnoreResults =
true;
349 llvm_unreachable(
"Invalid ObjC container.");
350 case Decl::ObjCInterface:
351 case Decl::ObjCImplementation:
354 case Decl::ObjCCategory: {
362 IgnoreResults =
true;
368 Out <<
"objc(ext)" << ID->
getName() <<
'@';
372 GenObjCCategory(ID->getName(), CD->
getName());
376 case Decl::ObjCCategoryImpl: {
384 IgnoreResults =
true;
387 GenObjCCategory(ID->getName(), CD->
getName());
390 case Decl::ObjCProtocol:
391 GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
408 VisitObjCPropertyDecl(PD);
412 IgnoreResults =
true;
415 void USRGenerator::VisitTagDecl(
const TagDecl *D) {
418 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
424 bool AlreadyStarted =
false;
425 if (
const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
427 AlreadyStarted =
true;
434 case TTK_Enum: llvm_unreachable(
"enum template");
436 VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
438 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
439 AlreadyStarted =
true;
446 case TTK_Enum: llvm_unreachable(
"enum partial specialization");
448 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
452 if (!AlreadyStarted) {
463 assert(Buf.size() > 0);
464 const unsigned off = Buf.size() - 1;
466 if (EmitDeclName(D)) {
481 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
484 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
486 VisitTemplateArgument(Args.get(I));
491 void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
492 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
494 const DeclContext *DC = D->getDeclContext();
495 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
501 void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
502 GenLoc(D, /*IncludeOffset=*/true);
506 bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
508 return IgnoreResults;
511 // Guard against null declarations in invalid code.
513 IgnoreResults = true;
517 // Use the location of canonical decl.
518 D = D->getCanonicalDecl();
521 IgnoreResults || printLoc(Out, D->getLocStart(),
522 Context->getSourceManager(), IncludeOffset);
524 return IgnoreResults;
527 void USRGenerator::VisitType(QualType T) {
528 // This method mangles in USR information for types. It can possibly
529 // just reuse the naming-mangling logic used by codegen, although the
530 // requirements for USRs might not be the same.
531 ASTContext &Ctx = *Context;
534 T = Ctx.getCanonicalType(T);
535 Qualifiers Q = T.getQualifiers();
544 Out << ((char) ('0
' + qVal));
546 // Mangle in ObjC GC qualifiers?
548 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
550 T = Expansion->getPattern();
553 if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
554 unsigned char c = '\0
';
555 switch (BT->getKind()) {
556 case BuiltinType::Void:
558 case BuiltinType::Bool:
560 case BuiltinType::UChar:
562 case BuiltinType::Char16:
564 case BuiltinType::Char32:
566 case BuiltinType::UShort:
568 case BuiltinType::UInt:
570 case BuiltinType::ULong:
572 case BuiltinType::ULongLong:
574 case BuiltinType::UInt128:
576 case BuiltinType::Char_U:
577 case BuiltinType::Char_S:
579 case BuiltinType::SChar:
581 case BuiltinType::WChar_S:
582 case BuiltinType::WChar_U:
584 case BuiltinType::Short:
586 case BuiltinType::Int:
588 case BuiltinType::Long:
590 case BuiltinType::LongLong:
592 case BuiltinType::Int128:
594 case BuiltinType::Half:
596 case BuiltinType::Float:
598 case BuiltinType::Double:
600 case BuiltinType::LongDouble:
602 case BuiltinType::NullPtr:
604 #define BUILTIN_TYPE(Id, SingletonId)
605 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
606 #include "clang/AST/BuiltinTypes.def"
607 case BuiltinType::Dependent:
608 case BuiltinType::OCLImage1d:
609 case BuiltinType::OCLImage1dArray:
610 case BuiltinType::OCLImage1dBuffer:
611 case BuiltinType::OCLImage2d:
612 case BuiltinType::OCLImage2dArray:
613 case BuiltinType::OCLImage2dDepth:
614 case BuiltinType::OCLImage2dArrayDepth:
615 case BuiltinType::OCLImage2dMSAA:
616 case BuiltinType::OCLImage2dArrayMSAA:
617 case BuiltinType::OCLImage2dMSAADepth:
618 case BuiltinType::OCLImage2dArrayMSAADepth:
619 case BuiltinType::OCLImage3d:
620 case BuiltinType::OCLEvent:
621 case BuiltinType::OCLClkEvent:
622 case BuiltinType::OCLQueue:
623 case BuiltinType::OCLNDRange:
624 case BuiltinType::OCLReserveID:
625 case BuiltinType::OCLSampler:
626 IgnoreResults = true;
628 case BuiltinType::ObjCId:
630 case BuiltinType::ObjCClass:
632 case BuiltinType::ObjCSel:
639 // If we have already seen this (non-built-in) type, use a substitution
641 llvm::DenseMap<const Type *, unsigned>::iterator Substitution
642 = TypeSubstitutions.find(T.getTypePtr());
643 if (Substitution != TypeSubstitutions.end()) {
644 Out << 'S' << Substitution->second << '_
';
647 // Record this as a substitution.
648 unsigned Number = TypeSubstitutions.size();
649 TypeSubstitutions[T.getTypePtr()] = Number;
652 if (const PointerType *PT = T->getAs<PointerType>()) {
654 T = PT->getPointeeType();
657 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
659 T = RT->getPointeeType();
662 if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
664 T = RT->getPointeeType();
667 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
669 VisitType(FT->getReturnType());
670 for (const auto &I : FT->param_types())
672 if (FT->isVariadic())
676 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
678 T = BT->getPointeeType();
681 if (const ComplexType *CT = T->getAs<ComplexType>()) {
683 T = CT->getElementType();
686 if (const TagType *TT = T->getAs<TagType>()) {
688 VisitTagDecl(TT->getDecl());
691 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
692 Out << 't
' << TTP->getDepth() << '.
' << TTP->getIndex();
695 if (const TemplateSpecializationType *Spec
696 = T->getAs<TemplateSpecializationType>()) {
698 VisitTemplateName(Spec->getTemplateName());
699 Out << Spec->getNumArgs();
700 for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
701 VisitTemplateArgument(Spec->getArg(I));
704 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
706 // FIXME: Encode the qualifier, don't just print it.
709 PO.SuppressUnwrittenScope =
true;
710 PO.ConstantArraySizeAsWritten =
false;
711 PO.AnonymousTagLocations =
false;
712 DNT->getQualifier()->print(Out, PO);
713 Out <<
':' << DNT->getIdentifier()->getName();
717 T = InjT->getInjectedSpecializationType();
727 void USRGenerator::VisitTemplateParameterList(
731 Out << '>
' << Params->size();
732 for (TemplateParameterList::const_iterator P = Params->begin(),
733 PEnd = Params->end();
736 if (isa<TemplateTypeParmDecl>(*P)) {
737 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
743 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
744 if (NTTP->isParameterPack())
747 VisitType(NTTP->getType());
751 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
752 if (TTP->isParameterPack())
755 VisitTemplateParameterList(TTP->getTemplateParameters());
759 void USRGenerator::VisitTemplateName(TemplateName Name) {
760 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
761 if (TemplateTemplateParmDecl *TTP
762 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
763 Out << 't
' << TTP->getDepth() << '.
' << TTP->getIndex();
771 // FIXME: Visit dependent template names.
774 void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
775 switch (Arg.getKind()) {
776 case TemplateArgument::Null:
779 case TemplateArgument::Declaration:
780 Visit(Arg.getAsDecl());
783 case TemplateArgument::NullPtr:
786 case TemplateArgument::TemplateExpansion:
787 Out << 'P
'; // pack expansion of...
789 case TemplateArgument::Template:
790 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
793 case TemplateArgument::Expression:
794 // FIXME: Visit expressions.
797 case TemplateArgument::Pack:
798 Out << 'p' << Arg.pack_size();
799 for (const auto &P : Arg.pack_elements())
800 VisitTemplateArgument(P);
803 case TemplateArgument::Type:
804 VisitType(Arg.getAsType());
807 case TemplateArgument::Integral:
809 VisitType(Arg.getIntegralType());
810 Out << Arg.getAsIntegral();
815 //===----------------------------------------------------------------------===//
816 // USR generation functions.
817 //===----------------------------------------------------------------------===//
819 void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS) {
820 OS << "objc(cs)" << Cls;
823 void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
825 OS << "objc(cy)" << Cls << '@
' << Cat;
828 void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
832 void clang::index::generateUSRForObjCMethod(StringRef Sel,
833 bool IsInstanceMethod,
835 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
838 void clang::index::generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS) {
839 OS << "(py)" << Prop;
842 void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS) {
843 OS << "objc(pl)" << Prot;
846 bool clang::index::generateUSRForDecl(const Decl *D,
847 SmallVectorImpl<char> &Buf) {
848 // Don't generate USRs
for things with invalid locations.
854 return UG.ignoreResults();
864 llvm::raw_svector_ostream Out(Buf);
872 if (ShouldGenerateLocation)
Defines the clang::ASTContext interface.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
bool generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl< char > &Buf)
Generate a USR for a macro, including the USR prefix.
A (possibly-)qualified type.
ObjCInterfaceDecl * getClassInterface()
ObjCInterfaceDecl * getClassInterface()
TypedefDecl - Represents the declaration of a typedef-name via the 'typedef' type specifier...
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
Decl - This represents one declaration (or definition), e.g.
Defines the C++ template declaration subclasses.
NamespaceDecl - Represent a C++ namespace.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
The "__interface" keyword.
ObjCMethodDecl - Represents an instance or class method declaration.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Describes how types, statements, expressions, and declarations should be printed. ...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Represents a class template specialization, which refers to a class template with a given set of temp...
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
static StringRef getUSRSpacePrefix()
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Record the location of a macro definition.
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, const SourceManager &SM, bool IncludeOffset)
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
TagKind getTagKind() const
bool IsClassExtension() const
Represents a C++ using-declaration.
ObjCContainerDecl - Represents a container for method declarations.
const LangOptions & getLangOpts() const
Represents an Objective-C protocol declaration.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Represents an ObjC class declaration.
Represents a linkage specification.
detail::InMemoryDirectory::const_iterator I
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
SourceLocation getLocStart() const LLVM_READONLY
ID
Defines the set of possible language-specific address spaces.
StringRef getName() const
Return the actual identifier string.
Declaration of a template type parameter.
DeclContext * getDeclContext()
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a C++ template name within the type system.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isInstanceMethod() const
bool isExternallyVisible() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isEmbeddedInDeclarator() const
const char * getName() const
Encodes a location in the source.
TagDecl - Represents the declaration of a struct/union/class/enum.
ASTContext & getASTContext() const LLVM_READONLY
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a dependent using declaration which was not marked with typename.
Cached information about one file (either on disk or in the virtual file system). ...
void printName(raw_ostream &os) const
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
Represents one property declaration in an Objective-C interface.
bool SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
const IdentifierInfo * getName() const
Retrieve the name of the macro being defined.
The injected class name of a C++ class template or class template partial specialization.
Base class for declarations which introduce a typedef-name.
Represents a template argument.
void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS)
Generate a USR fragment for an Objective-C protocol.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static __inline__ uint32_t volatile uint32_t * p
bool isFreeStanding() const
Represents a dependent using declaration which was marked with typename.
DeclarationName - The name of a declaration.
Selector getSelector() const
const T * getAs() const
Member-template getAs<specific type>'.
SourceManager & getSourceManager()
A template argument list.
ObjCPropertyDecl * getPropertyDecl() const
Represents a C++ struct/union/class.
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
Declaration of a class template.
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS)
Generate a USR fragment for an Objective-C class.
SourceLocation getLocation() const
Retrieve the location of the macro name in the definition.
void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS)
Generate a USR fragment for an Objective-C class category.
const ObjCInterfaceDecl * getObjContainingInterface(const NamedDecl *ND) const
Returns the Objective-C interface that ND belongs to if it is an Objective-C method/property/ivar etc...
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
Represents a C++ namespace alias.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Represents C++ using-directive.
A simple visitor class that helps create declaration visitors.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
This class handles loading and caching of source files into memory.
Declaration of a template function.
void generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS)
Generate a USR fragment for an Objective-C property.