aboutsummaryrefslogtreecommitdiff
path: root/lib/Index/USRGeneration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Index/USRGeneration.cpp')
-rw-r--r--lib/Index/USRGeneration.cpp32
1 files changed, 28 insertions, 4 deletions
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 30f1add249b1..58f61c3c65b7 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -12,7 +12,6 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/Lex/PreprocessingRecord.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
@@ -174,8 +173,11 @@ bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
return false;
if (D->getParentFunctionOrMethod())
return true;
+ SourceLocation Loc = D->getLocation();
+ if (Loc.isInvalid())
+ return false;
const SourceManager &SM = Context->getSourceManager();
- return !SM.isInSystemHeader(D->getLocation());
+ return !SM.isInSystemHeader(Loc);
}
void USRGenerator::VisitDeclContext(const DeclContext *DC) {
@@ -284,6 +286,15 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) {
VisitDeclContext(D->getDeclContext());
+ if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
+ Out << "@VT";
+ VisitTemplateParameterList(VarTmpl->getTemplateParameters());
+ } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
+ = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
+ Out << "@VP";
+ VisitTemplateParameterList(PartialSpec->getTemplateParameters());
+ }
+
// Variables always have simple names.
StringRef s = D->getName();
@@ -295,6 +306,17 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) {
IgnoreResults = true;
else
Out << '@' << s;
+
+ // For a template specialization, mangle the template arguments.
+ if (const VarTemplateSpecializationDecl *Spec
+ = dyn_cast<VarTemplateSpecializationDecl>(D)) {
+ const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+ Out << '>';
+ for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+ Out << '#';
+ VisitTemplateArgument(Args.get(I));
+ }
+ }
}
void USRGenerator::VisitNonTypeTemplateParmDecl(
@@ -875,9 +897,11 @@ void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS) {
bool clang::index::generateUSRForDecl(const Decl *D,
SmallVectorImpl<char> &Buf) {
- // Don't generate USRs for things with invalid locations.
- if (!D || D->getLocStart().isInvalid())
+ if (!D)
return true;
+ // We don't ignore decls with invalid source locations. Implicit decls, like
+ // C++'s operator new function, can have invalid locations but it is fine to
+ // create USRs that can identify them.
USRGenerator UG(&D->getASTContext(), Buf);
UG.Visit(D);