MaskRay created this revision.
Herald added a subscriber: cfe-commits.

CXIdxEntityRefInfo contains the member `CXIdxEntityRefKind kind;` to
differentiate implicit and direct calls. However, there are more roles
defined in SymbolRole. Among them, `Read/Write` are probably the most
useful ones as they can be used to differentiate Read/Write occurrences
of a symbol for document highlight in a text document.

See `export namespace DocumentHighlightKind`
on https://microsoft.github.io/language-server-protocol/specification


Repository:
  rC Clang

https://reviews.llvm.org/D42895

Files:
  include/clang-c/Index.h
  tools/libclang/CXIndexDataConsumer.cpp
  tools/libclang/CXIndexDataConsumer.h

Index: tools/libclang/CXIndexDataConsumer.h
===================================================================
--- tools/libclang/CXIndexDataConsumer.h
+++ tools/libclang/CXIndexDataConsumer.h
@@ -436,13 +436,15 @@
                        const NamedDecl *Parent,
                        const DeclContext *DC,
                        const Expr *E = nullptr,
-                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
+                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct,
+                       CXSymbolRole Role = CXSymbolRole_None);
 
   bool handleReference(const NamedDecl *D, SourceLocation Loc,
                        const NamedDecl *Parent,
                        const DeclContext *DC,
                        const Expr *E = nullptr,
-                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
+                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct,
+                       CXSymbolRole Role = CXSymbolRole_None);
 
   bool isNotFromSourceFile(SourceLocation Loc) const;
 
Index: tools/libclang/CXIndexDataConsumer.cpp
===================================================================
--- tools/libclang/CXIndexDataConsumer.cpp
+++ tools/libclang/CXIndexDataConsumer.cpp
@@ -148,6 +148,29 @@
     return true;
   }
 };
+
+CXSymbolRole getSymbolRole(SymbolRoleSet Roles) {
+  unsigned R = 0;
+  if (Roles & (unsigned)SymbolRole::Declaration)
+    R |= CXSymbolRole_Declaration;
+  if (Roles & (unsigned)SymbolRole::Definition)
+    R |= CXSymbolRole_Definition;
+  if (Roles & (unsigned)SymbolRole::Reference)
+    R |= CXSymbolRole_Reference;
+  if (Roles & (unsigned)SymbolRole::Read)
+    R |= CXSymbolRole_Read;
+  if (Roles & (unsigned)SymbolRole::Write)
+    R |= CXSymbolRole_Write;
+  if (Roles & (unsigned)SymbolRole::Call)
+    R |= CXSymbolRole_Call;
+  if (Roles & (unsigned)SymbolRole::Dynamic)
+    R |= CXSymbolRole_Dynamic;
+  if (Roles & (unsigned)SymbolRole::AddressOf)
+    R |= CXSymbolRole_AddressOf;
+  if (Roles & (unsigned)SymbolRole::Implicit)
+    R |= CXSymbolRole_Implicit;
+  return CXSymbolRole(R);
+}
 }
 
 bool CXIndexDataConsumer::handleDeclOccurence(const Decl *D,
@@ -184,6 +207,7 @@
     if (Roles & (unsigned)SymbolRole::Implicit) {
       Kind = CXIdxEntityRef_Implicit;
     }
+    CXSymbolRole CXRole = getSymbolRole(Roles);
 
     CXCursor Cursor;
     if (ASTNode.OrigE) {
@@ -202,7 +226,7 @@
     }
     handleReference(ND, Loc, Cursor,
                     dyn_cast_or_null<NamedDecl>(ASTNode.Parent),
-                    ASTNode.ContainerDC, ASTNode.OrigE, Kind);
+                    ASTNode.ContainerDC, ASTNode.OrigE, Kind, CXRole);
 
   } else {
     const DeclContext *LexicalDC = ASTNode.ContainerDC;
@@ -889,21 +913,23 @@
                                       const NamedDecl *Parent,
                                       const DeclContext *DC,
                                       const Expr *E,
-                                      CXIdxEntityRefKind Kind) {
+                                      CXIdxEntityRefKind Kind,
+                                      CXSymbolRole Role) {
   if (!D || !DC)
     return false;
 
   CXCursor Cursor = E ? MakeCXCursor(E, cast<Decl>(DC), CXTU)
                       : getRefCursor(D, Loc);
-  return handleReference(D, Loc, Cursor, Parent, DC, E, Kind);
+  return handleReference(D, Loc, Cursor, Parent, DC, E, Kind, Role);
 }
 
 bool CXIndexDataConsumer::handleReference(const NamedDecl *D, SourceLocation Loc,
                                       CXCursor Cursor,
                                       const NamedDecl *Parent,
                                       const DeclContext *DC,
                                       const Expr *E,
-                                      CXIdxEntityRefKind Kind) {
+                                      CXIdxEntityRefKind Kind,
+                                      CXSymbolRole Role) {
   if (!CB.indexEntityReference)
     return false;
 
@@ -939,7 +965,8 @@
                               getIndexLoc(Loc),
                               &RefEntity,
                               Parent ? &ParentEntity : nullptr,
-                              &Container };
+                              &Container,
+                              Role };
   CB.indexEntityReference(ClientData, &Info);
   return true;
 }
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -32,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 47
+#define CINDEX_VERSION_MINOR 48
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
       ((major) * 10000)                       \
@@ -6095,7 +6095,9 @@
  */
 typedef enum {
   /**
-   * \brief The entity is referenced directly in user's code.
+   * \brief DEPRECATED: The entity is referenced directly in user's code.
+   *
+   * Use CXSymbolRole_Implicit instead.
    */
   CXIdxEntityRef_Direct = 1,
   /**
@@ -6105,6 +6107,22 @@
   CXIdxEntityRef_Implicit = 2
 } CXIdxEntityRefKind;
 
+/**
+ * \brief Roles that are attributed to symbol occurrences.
+ */
+typedef enum {
+  CXSymbolRole_None = 0,
+  CXSymbolRole_Declaration = 1 << 0,
+  CXSymbolRole_Definition = 1 << 1,
+  CXSymbolRole_Reference = 1 << 2,
+  CXSymbolRole_Read = 1 << 3,
+  CXSymbolRole_Write = 1 << 4,
+  CXSymbolRole_Call = 1 << 5,
+  CXSymbolRole_Dynamic = 1 << 6,
+  CXSymbolRole_AddressOf = 1 << 7,
+  CXSymbolRole_Implicit = 1 << 8
+} CXSymbolRole;
+
 /**
  * \brief Data for IndexerCallbacks#indexEntityReference.
  */
@@ -6135,6 +6153,10 @@
    * \brief Lexical container context of the reference.
    */
   const CXIdxContainerInfo *container;
+  /**
+   * \brief Sets of symbol roles of the reference.
+   */
+  CXSymbolRole role;
 } CXIdxEntityRefInfo;
 
 /**
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to