diff options
Diffstat (limited to 'lib/Index/USRGeneration.cpp')
| -rw-r--r-- | lib/Index/USRGeneration.cpp | 54 | 
1 files changed, 48 insertions, 6 deletions
| diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp index e08b85e9f868..baa166ee2802 100644 --- a/lib/Index/USRGeneration.cpp +++ b/lib/Index/USRGeneration.cpp @@ -198,7 +198,9 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {      return;    VisitDeclContext(D->getDeclContext()); +  bool IsTemplate = false;    if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) { +    IsTemplate = true;      Out << "@FT@";      VisitTemplateParameterList(FunTmpl->getTemplateParameters());    } else @@ -226,12 +228,26 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {    }    if (D->isVariadic())      Out << '.'; +  if (IsTemplate) { +    // Function templates can be overloaded by return type, for example: +    // \code +    //   template <class T> typename T::A foo() {} +    //   template <class T> typename T::B foo() {} +    // \endcode +    Out << '#'; +    VisitType(D->getReturnType()); +  }    Out << '#';    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {      if (MD->isStatic())        Out << 'S';      if (unsigned quals = MD->getTypeQualifiers())        Out << (char)('0' + quals); +    switch (MD->getRefQualifier()) { +    case RQ_None: break; +    case RQ_LValue: Out << '&'; break; +    case RQ_RValue: Out << "&&"; break; +    }    }  } @@ -414,8 +430,8 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {        switch (D->getTagKind()) {        case TTK_Interface: +      case TTK_Class:        case TTK_Struct: Out << "@ST"; break; -      case TTK_Class:  Out << "@CT"; break;        case TTK_Union:  Out << "@UT"; break;        case TTK_Enum: llvm_unreachable("enum template");        } @@ -426,8 +442,8 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {        switch (D->getTagKind()) {        case TTK_Interface: +      case TTK_Class:        case TTK_Struct: Out << "@SP"; break; -      case TTK_Class:  Out << "@CP"; break;        case TTK_Union:  Out << "@UP"; break;        case TTK_Enum: llvm_unreachable("enum partial specialization");        }       @@ -438,8 +454,8 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {    if (!AlreadyStarted) {      switch (D->getTagKind()) {        case TTK_Interface: +      case TTK_Class:        case TTK_Struct: Out << "@S"; break; -      case TTK_Class:  Out << "@C"; break;        case TTK_Union:  Out << "@U"; break;        case TTK_Enum:   Out << "@E"; break;      } @@ -455,9 +471,13 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {        Buf[off] = 'A';        Out << '@' << *TD;      } -    else +  else { +    if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) { +      printLoc(Out, D->getLocation(), Context->getSourceManager(), true); +    } else        Buf[off] = 'a';    } +  }    // For a class template specialization, mangle the template arguments.    if (const ClassTemplateSpecializationDecl *Spec @@ -540,7 +560,6 @@ void USRGenerator::VisitType(QualType T) {            c = 'v'; break;          case BuiltinType::Bool:            c = 'b'; break; -        case BuiltinType::Char_U:          case BuiltinType::UChar:            c = 'c'; break;          case BuiltinType::Char16: @@ -557,9 +576,11 @@ void USRGenerator::VisitType(QualType T) {            c = 'k'; break;          case BuiltinType::UInt128:            c = 'j'; break; +        case BuiltinType::Char_U:          case BuiltinType::Char_S: -        case BuiltinType::SChar:            c = 'C'; break; +        case BuiltinType::SChar: +          c = 'r'; break;          case BuiltinType::WChar_S:          case BuiltinType::WChar_U:            c = 'W'; break; @@ -626,6 +647,11 @@ void USRGenerator::VisitType(QualType T) {        T = PT->getPointeeType();        continue;      } +    if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) { +      Out << "&&"; +      T = RT->getPointeeType(); +      continue; +    }      if (const ReferenceType *RT = T->getAs<ReferenceType>()) {        Out << '&';        T = RT->getPointeeType(); @@ -668,6 +694,22 @@ void USRGenerator::VisitType(QualType T) {          VisitTemplateArgument(Spec->getArg(I));        return;      } +    if (const DependentNameType *DNT = T->getAs<DependentNameType>()) { +      Out << '^'; +      // FIXME: Encode the qualifier, don't just print it. +      PrintingPolicy PO(Ctx.getLangOpts()); +      PO.SuppressTagKeyword = true; +      PO.SuppressUnwrittenScope = true; +      PO.ConstantArraySizeAsWritten = false; +      PO.AnonymousTagLocations = false; +      DNT->getQualifier()->print(Out, PO); +      Out << ':' << DNT->getIdentifier()->getName(); +      return; +    } +    if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) { +      T = InjT->getInjectedSpecializationType(); +      continue; +    }      // Unhandled type.      Out << ' '; | 
