mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-02 13:12:09 +00:00
[index] Add a caller relation for a call reference.
llvm-svn: 262207
This commit is contained in:
parent
c97c7c88c0
commit
a8b51c1e20
@ -88,8 +88,9 @@ enum class SymbolRole : uint16_t {
|
||||
RelationBaseOf = 1 << 10,
|
||||
RelationOverrideOf = 1 << 11,
|
||||
RelationReceivedBy = 1 << 12,
|
||||
RelationCalledBy = 1 << 13,
|
||||
};
|
||||
static const unsigned SymbolRoleBitNum = 13;
|
||||
static const unsigned SymbolRoleBitNum = 14;
|
||||
typedef unsigned SymbolRoleSet;
|
||||
|
||||
/// Represents a relation to another symbol for a symbol occurrence.
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
|
||||
} else if (auto CE = dyn_cast<CallExpr>(Parent)) {
|
||||
if (CE->getCallee()->IgnoreParenCasts() == E) {
|
||||
Roles |= (unsigned)SymbolRole::Call;
|
||||
addCallRole(Roles, Relations);
|
||||
if (auto *ME = dyn_cast<MemberExpr>(E)) {
|
||||
if (auto *CXXMD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
|
||||
if (CXXMD->isVirtual() && !ME->hasQualifier()) {
|
||||
@ -120,6 +120,15 @@ public:
|
||||
return Roles;
|
||||
}
|
||||
|
||||
void addCallRole(SymbolRoleSet &Roles,
|
||||
SmallVectorImpl<SymbolRelation> &Relations) {
|
||||
Roles |= (unsigned)SymbolRole::Call;
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(ParentDC))
|
||||
Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, FD);
|
||||
else if (auto *MD = dyn_cast<ObjCMethodDecl>(ParentDC))
|
||||
Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, MD);
|
||||
}
|
||||
|
||||
bool VisitDeclRefExpr(DeclRefExpr *E) {
|
||||
SmallVector<SymbolRelation, 4> Relations;
|
||||
SymbolRoleSet Roles = getRolesForRef(E, Relations);
|
||||
@ -169,11 +178,12 @@ public:
|
||||
};
|
||||
|
||||
if (ObjCMethodDecl *MD = E->getMethodDecl()) {
|
||||
SymbolRoleSet Roles = (unsigned)SymbolRole::Call;
|
||||
SymbolRoleSet Roles{};
|
||||
SmallVector<SymbolRelation, 2> Relations;
|
||||
addCallRole(Roles, Relations);
|
||||
if (E->isImplicit())
|
||||
Roles |= (unsigned)SymbolRole::Implicit;
|
||||
|
||||
SmallVector<SymbolRelation, 2> Relations;
|
||||
if (isDynamic(E)) {
|
||||
Roles |= (unsigned)SymbolRole::Dynamic;
|
||||
if (auto *RecD = E->getReceiverInterface())
|
||||
@ -206,39 +216,42 @@ public:
|
||||
Parent, ParentDC, SymbolRoleSet(), {}, E);
|
||||
}
|
||||
|
||||
bool passObjCLiteralMethodCall(const ObjCMethodDecl *MD, const Expr *E) {
|
||||
SymbolRoleSet Roles{};
|
||||
SmallVector<SymbolRelation, 2> Relations;
|
||||
addCallRole(Roles, Relations);
|
||||
Roles |= (unsigned)SymbolRole::Implicit;
|
||||
return IndexCtx.handleReference(MD, E->getLocStart(),
|
||||
Parent, ParentDC, Roles, Relations, E);
|
||||
}
|
||||
|
||||
bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
||||
if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
|
||||
SymbolRoleSet Roles = (unsigned)SymbolRole::Call;
|
||||
Roles |= (unsigned)SymbolRole::Implicit;
|
||||
return IndexCtx.handleReference(MD, E->getLocStart(),
|
||||
Parent, ParentDC, Roles, {}, E);
|
||||
return passObjCLiteralMethodCall(MD, E);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
|
||||
if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) {
|
||||
SymbolRoleSet Roles = (unsigned)SymbolRole::Call;
|
||||
Roles |= (unsigned)SymbolRole::Implicit;
|
||||
return IndexCtx.handleReference(MD, E->getLocStart(),
|
||||
Parent, ParentDC, Roles, {}, E);
|
||||
return passObjCLiteralMethodCall(MD, E);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
||||
if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) {
|
||||
SymbolRoleSet Roles = (unsigned)SymbolRole::Call;
|
||||
Roles |= (unsigned)SymbolRole::Implicit;
|
||||
return IndexCtx.handleReference(MD, E->getLocStart(),
|
||||
Parent, ParentDC, Roles, {}, E);
|
||||
return passObjCLiteralMethodCall(MD, E);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitCXXConstructExpr(CXXConstructExpr *E) {
|
||||
SymbolRoleSet Roles{};
|
||||
SmallVector<SymbolRelation, 2> Relations;
|
||||
addCallRole(Roles, Relations);
|
||||
return IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
|
||||
Parent, ParentDC, (unsigned)SymbolRole::Call, {}, E);
|
||||
Parent, ParentDC, Roles, Relations, E);
|
||||
}
|
||||
|
||||
bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
|
||||
|
@ -206,6 +206,7 @@ void index::applyForEachSymbolRole(SymbolRoleSet Roles,
|
||||
APPLY_FOR_ROLE(RelationBaseOf);
|
||||
APPLY_FOR_ROLE(RelationOverrideOf);
|
||||
APPLY_FOR_ROLE(RelationReceivedBy);
|
||||
APPLY_FOR_ROLE(RelationCalledBy);
|
||||
|
||||
#undef APPLY_FOR_ROLE
|
||||
}
|
||||
@ -231,6 +232,7 @@ void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
|
||||
case SymbolRole::RelationBaseOf: OS << "RelBase"; break;
|
||||
case SymbolRole::RelationOverrideOf: OS << "RelOver"; break;
|
||||
case SymbolRole::RelationReceivedBy: OS << "RelRec"; break;
|
||||
case SymbolRole::RelationCalledBy: OS << "RelCall"; break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -10,9 +10,11 @@
|
||||
void foo();
|
||||
// CHECK: [[@LINE+1]]:6 | function/C | goo | c:@F@goo | _goo | Def | rel: 0
|
||||
void goo(Base *b) {
|
||||
// CHECK: [[@LINE+1]]:3 | function/C | foo | c:@F@foo | _foo | Ref,Call | rel: 0
|
||||
// CHECK: [[@LINE+2]]:3 | function/C | foo | c:@F@foo | _foo | Ref,Call,RelCall | rel: 1
|
||||
// CHECK-NEXT: RelCall | goo | c:@F@goo
|
||||
foo();
|
||||
// CHECK: [[@LINE+2]]:6 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Ref,Call,Dyn,RelRec | rel: 1
|
||||
// CHECK: [[@LINE+3]]:6 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Ref,Call,Dyn,RelRec,RelCall | rel: 2
|
||||
// CHECK-NEXT: RelCall | goo | c:@F@goo
|
||||
// CHECK-NEXT: RelRec | Base | c:objc(cs)Base
|
||||
[b meth];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user