summaryrefslogtreecommitdiff
path: root/lib/Index
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Index')
-rw-r--r--lib/Index/IndexBody.cpp26
-rw-r--r--lib/Index/IndexDecl.cpp2
-rw-r--r--lib/Index/IndexSymbol.cpp4
-rw-r--r--lib/Index/IndexingContext.cpp14
4 files changed, 39 insertions, 7 deletions
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index d3632b8b9b15f..6bbd38102509f 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -230,7 +230,31 @@ public:
SmallVector<SymbolRelation, 2> Relations;
addCallRole(Roles, Relations);
Stmt *Containing = getParentStmt();
- if (E->isImplicit() || (Containing && isa<PseudoObjectExpr>(Containing)))
+
+ auto IsImplicitProperty = [](const PseudoObjectExpr *POE) -> bool {
+ const auto *E = POE->getSyntacticForm();
+ if (const auto *BinOp = dyn_cast<BinaryOperator>(E))
+ E = BinOp->getLHS();
+ const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E);
+ if (!PRE)
+ return false;
+ if (PRE->isExplicitProperty())
+ return false;
+ if (const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
+ // Class properties that are explicitly defined using @property
+ // declarations are represented implicitly as there is no ivar for
+ // class properties.
+ if (Getter->isClassMethod() &&
+ Getter->getCanonicalDecl()->findPropertyDecl())
+ return false;
+ }
+ return true;
+ };
+ bool IsPropCall = Containing && isa<PseudoObjectExpr>(Containing);
+ // Implicit property message sends are not 'implicit'.
+ if ((E->isImplicit() || IsPropCall) &&
+ !(IsPropCall &&
+ IsImplicitProperty(cast<PseudoObjectExpr>(Containing))))
Roles |= (unsigned)SymbolRole::Implicit;
if (isDynamic(E)) {
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index d1127722c8ca3..c5230c0f9acf8 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -618,6 +618,8 @@ public:
Template.is<ClassTemplateDecl *>()
? (Decl *)Template.get<ClassTemplateDecl *>()
: Template.get<ClassTemplatePartialSpecializationDecl *>();
+ if (!D->isThisDeclarationADefinition())
+ IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
IndexCtx.indexTagDecl(
D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
SpecializationOf));
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index bf358a3721490..0dc3720208caf 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -69,11 +69,13 @@ bool index::isFunctionLocalSymbol(const Decl *D) {
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
switch (ND->getFormalLinkage()) {
case NoLinkage:
- case VisibleNoLinkage:
case InternalLinkage:
return true;
+ case VisibleNoLinkage:
case UniqueExternalLinkage:
+ case ModuleInternalLinkage:
llvm_unreachable("Not a sema linkage");
+ case ModuleLinkage:
case ExternalLinkage:
return false;
}
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index 754bc84ff4b2a..c4aa51d62f02d 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -229,6 +229,12 @@ static bool isDeclADefinition(const Decl *D, const DeclContext *ContainerDC, AST
return false;
}
+/// Whether the given NamedDecl should be skipped because it has no name.
+static bool shouldSkipNamelessDecl(const NamedDecl *ND) {
+ return ND->getDeclName().isEmpty() && !isa<TagDecl>(ND) &&
+ !isa<ObjCCategoryDecl>(ND);
+}
+
static const Decl *adjustParent(const Decl *Parent) {
if (!Parent)
return nullptr;
@@ -243,8 +249,8 @@ static const Decl *adjustParent(const Decl *Parent) {
} else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
if (RD->isAnonymousStructOrUnion())
continue;
- } else if (auto FD = dyn_cast<FieldDecl>(Parent)) {
- if (FD->getDeclName().isEmpty())
+ } else if (auto ND = dyn_cast<NamedDecl>(Parent)) {
+ if (shouldSkipNamelessDecl(ND))
continue;
}
return Parent;
@@ -315,9 +321,7 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
const DeclContext *ContainerDC) {
if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
return true;
- if (!isa<NamedDecl>(D) ||
- (cast<NamedDecl>(D)->getDeclName().isEmpty() &&
- !isa<TagDecl>(D) && !isa<ObjCCategoryDecl>(D)))
+ if (!isa<NamedDecl>(D) || shouldSkipNamelessDecl(cast<NamedDecl>(D)))
return true;
SourceManager &SM = Ctx->getSourceManager();