From f12918d218b76ce442cd7e0c6b65620bf2d35805 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 2 Nov 2016 23:42:33 +0000 Subject: [PATCH] [index] Fix assertion hit when handling a declaration of C++'s 'operator new' function. Part of this is to allow creating a USR for the canonical decl of that which is implicit and does not have a source location. rdar://28978992 llvm-svn: 285868 --- clang/lib/Index/IndexingContext.cpp | 10 ---------- clang/lib/Index/USRGeneration.cpp | 11 ++++++++--- clang/test/Index/Core/index-source.cpp | 6 ++++++ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/clang/lib/Index/IndexingContext.cpp b/clang/lib/Index/IndexingContext.cpp index bcc367c6626d..21869d88a570 100644 --- a/clang/lib/Index/IndexingContext.cpp +++ b/clang/lib/Index/IndexingContext.cpp @@ -290,19 +290,9 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, Roles |= (unsigned)SymbolRole::Declaration; D = getCanonicalDecl(D); - if (D->isImplicit() && !isa(D) && - !(isa(D) && cast(D)->getBuiltinID())) { - // operator new declarations will link to the implicit one as canonical. - return true; - } Parent = adjustParent(Parent); if (Parent) Parent = getCanonicalDecl(Parent); - assert((!Parent || !Parent->isImplicit() || - (isa(Parent) && - cast(Parent)->getBuiltinID()) || - isa(Parent) || isa(Parent)) && - "unexpected implicit parent!"); SmallVector FinalRelations; FinalRelations.reserve(Relations.size()+1); diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 6a114f934a9d..bec777ddf4f9 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -173,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) { @@ -874,9 +877,11 @@ void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS) { bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl &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); diff --git a/clang/test/Index/Core/index-source.cpp b/clang/test/Index/Core/index-source.cpp index c4e12903f6cd..11ac89529dd0 100644 --- a/clang/test/Index/Core/index-source.cpp +++ b/clang/test/Index/Core/index-source.cpp @@ -19,3 +19,9 @@ class BT { return { .idx = 0 }; // Make sure this doesn't trigger a crash. } }; + +// CHECK: [[@LINE+1]]:23 | type-alias/C | size_t | +typedef unsigned long size_t; +// CHECK: [[@LINE+2]]:7 | function/C | operator new | c:@F@operator new#l# | __Znwm | +// CHECK: [[@LINE+1]]:20 | type-alias/C | size_t | {{.*}} | Ref | +void* operator new(size_t sz);