[clangd] Downrank symbols with reserved names (score *= 0.1)

Reviewers: ilya-biryukov

Subscribers: klimek, ioeric, MaskRay, jkorous, cfe-commits

Differential Revision: https://reviews.llvm.org/D47707

llvm-svn: 334274
diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp
index 0049027..e42fca4 100644
--- a/clang-tools-extra/clangd/Quality.cpp
+++ b/clang-tools-extra/clangd/Quality.cpp
@@ -9,6 +9,7 @@
 #include "Quality.h"
 #include "index/Index.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/Basic/CharInfo.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
@@ -19,6 +20,11 @@
 namespace clang {
 namespace clangd {
 using namespace llvm;
+static bool IsReserved(StringRef Name) {
+  // FIXME: Should we exclude _Bool and others recognized by the standard?
+  return Name.size() >= 2 && Name[0] == '_' &&
+         (isUppercase(Name[1]) || Name[1] == '_');
+}
 
 static bool hasDeclInMainFile(const Decl &D) {
   auto &SourceMgr = D.getASTContext().getSourceManager();
@@ -101,11 +107,18 @@
     Category = categorize(*SemaCCResult.Declaration);
   else if (SemaCCResult.Kind == CodeCompletionResult::RK_Macro)
     Category = Macro;
+
+  if (SemaCCResult.Declaration) {
+    if (auto *ID = SemaCCResult.Declaration->getIdentifier())
+      ReservedName = ReservedName || IsReserved(ID->getName());
+  } else if (SemaCCResult.Kind == CodeCompletionResult::RK_Macro)
+    ReservedName = ReservedName || IsReserved(SemaCCResult.Macro->getName());
 }
 
 void SymbolQualitySignals::merge(const Symbol &IndexResult) {
   References = std::max(IndexResult.References, References);
   Category = categorize(IndexResult.SymInfo);
+  ReservedName = ReservedName || IsReserved(IndexResult.Name);
 }
 
 float SymbolQualitySignals::evaluate() const {
@@ -118,6 +131,8 @@
 
   if (Deprecated)
     Score *= 0.1f;
+  if (ReservedName)
+    Score *= 0.1f;
 
   switch (Category) {
     case Type:
@@ -142,6 +157,7 @@
   OS << formatv("=== Symbol quality: {0}\n", S.evaluate());
   OS << formatv("\tReferences: {0}\n", S.References);
   OS << formatv("\tDeprecated: {0}\n", S.Deprecated);
+  OS << formatv("\tReserved name: {0}\n", S.ReservedName);
   OS << formatv("\tCategory: {0}\n", static_cast<int>(S.Category));
   return OS;
 }