[clang] 18f9e25 - [AST][clangd] Expose documentation of Attrs on hover.

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 12 12:16:46 PDT 2021


Author: Sam McCall
Date: 2021-08-12T21:16:37+02:00
New Revision: 18f9e25ce1fa43f8663bd03f908ef9b27a0788f8

URL: https://github.com/llvm/llvm-project/commit/18f9e25ce1fa43f8663bd03f908ef9b27a0788f8
DIFF: https://github.com/llvm/llvm-project/commit/18f9e25ce1fa43f8663bd03f908ef9b27a0788f8.diff

LOG: [AST][clangd] Expose documentation of Attrs on hover.

This adds a method to Attr to get at the documentation programmatically.

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

Added: 
    clang/unittests/AST/AttrTest.cpp

Modified: 
    clang-tools-extra/clangd/Hover.cpp
    clang-tools-extra/clangd/unittests/HoverTests.cpp
    clang/include/clang/AST/Attr.h
    clang/lib/AST/CMakeLists.txt
    clang/unittests/AST/CMakeLists.txt
    clang/utils/TableGen/ClangAttrEmitter.cpp
    clang/utils/TableGen/TableGen.cpp
    clang/utils/TableGen/TableGenBackends.h

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 228cd192e0576..d16a2ebcbfd7e 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -731,7 +731,7 @@ llvm::Optional<HoverInfo> getHoverContents(const Attr *A, ParsedAST &AST) {
     llvm::raw_string_ostream OS(HI.Definition);
     A->printPretty(OS, AST.getASTContext().getPrintingPolicy());
   }
-  // FIXME: attributes have documentation, can we get at that?
+  HI.Documentation = Attr::getDocumentation(A->getKind()).str();
   return HI;
 }
 

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 5841e7166abfa..54a27b7483512 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -12,6 +12,7 @@
 #include "TestIndex.h"
 #include "TestTU.h"
 #include "index/MemIndex.h"
+#include "clang/AST/Attr.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/None.h"
@@ -2384,7 +2385,7 @@ TEST(Hover, All) {
          HI.Name = "nonnull";
          HI.Kind = index::SymbolKind::Unknown; // FIXME: no suitable value
          HI.Definition = "__attribute__((nonnull))";
-         HI.Documentation = ""; // FIXME
+         HI.Documentation = Attr::getDocumentation(attr::NonNull).str();
        }},
   };
 

diff  --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index dbfecc1250490..651f98adc7330 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -109,6 +109,8 @@ class Attr : public AttributeCommonInfo {
 
   // Pretty print this attribute.
   void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+  static StringRef getDocumentation(attr::Kind);
 };
 
 class TypeAttr : public Attr {

diff  --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 35099fd0dacf8..2cb74a40b9800 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -13,6 +13,11 @@ clang_tablegen(Opcodes.inc
   SOURCE Interp/Opcodes.td
   TARGET Opcodes)
 
+clang_tablegen(AttrDocTable.cpp -gen-clang-attr-doc-table
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../include/
+  SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../include/clang/Basic/Attr.td
+  TARGET ClangAttrDocTable)
+
 add_clang_library(clangAST
   APValue.cpp
   ASTConcept.cpp
@@ -24,6 +29,7 @@ add_clang_library(clangAST
   ASTImporterLookupTable.cpp
   ASTStructuralEquivalence.cpp
   ASTTypeTraits.cpp
+  AttrDocTable.cpp
   AttrImpl.cpp
   Comment.cpp
   CommentBriefParser.cpp

diff  --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp
new file mode 100644
index 0000000000000..38e723f3ee090
--- /dev/null
+++ b/clang/unittests/AST/AttrTest.cpp
@@ -0,0 +1,24 @@
+//===- unittests/AST/AttrTests.cpp --- Attribute tests --------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Attr.h"
+#include "clang/Basic/AttrKinds.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+
+namespace {
+
+TEST(Attr, Doc) {
+  EXPECT_THAT(Attr::getDocumentation(attr::Used).str(),
+              testing::HasSubstr("The compiler must emit the definition even "
+                                 "if it appears to be unused"));
+}
+
+} // namespace

diff  --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt
index b04e2bdc20e8b..e33c74d7ce720 100644
--- a/clang/unittests/AST/CMakeLists.txt
+++ b/clang/unittests/AST/CMakeLists.txt
@@ -15,6 +15,7 @@ add_clang_unittest(ASTTests
   ASTTraverserTest.cpp
   ASTTypeTraitsTest.cpp
   ASTVectorTest.cpp
+  AttrTest.cpp
   CommentLexer.cpp
   CommentParser.cpp
   CommentTextTest.cpp

diff  --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index d679d58aaef17..5fc2d50f65fa8 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -4210,6 +4210,42 @@ void EmitClangAttrSubjectMatchRulesParserStringSwitches(RecordKeeper &Records,
   getPragmaAttributeSupport(Records).generateParsingHelpers(OS);
 }
 
+void EmitClangAttrDocTable(RecordKeeper &Records, raw_ostream &OS) {
+  emitSourceFileHeader("Clang attribute documentation", OS);
+
+  OS << R"cpp(
+  #include "clang/AST/Attr.h"
+  #include "llvm/ADT/StringRef.h"
+  )cpp";
+  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+  for (const auto *A : Attrs) {
+    if (!A->getValueAsBit("ASTNode"))
+      continue;
+    std::vector<Record *> Docs = A->getValueAsListOfDefs("Documentation");
+    for (const auto *D : Docs) {
+      OS << "\nstatic const char AttrDoc_" << A->getName() << "[] = "
+         << "R\"reST("
+         << D->getValueAsOptionalString("Content").getValueOr("").trim()
+         << ")reST\";\n";
+      // Only look at the first documentation if there are several.
+      // (Currently there's only one such attr, revisit if this becomes common).
+      break;
+    }
+  }
+  OS << R"cpp(
+  static const llvm::StringRef AttrDoc[] = {
+  #define ATTR(NAME) AttrDoc_##NAME,
+  #include "clang/Basic/AttrList.inc"
+  };
+
+  llvm::StringRef clang::Attr::getDocumentation(clang::attr::Kind K) {
+    if(K < llvm::array_lengthof(AttrDoc))
+      return AttrDoc[K];
+    return "";
+  }
+  )cpp";
+}
+
 enum class SpellingKind {
   GNU,
   CXX11,

diff  --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp
index 7fb5d0acc6f38..bb9366e2b7fc0 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -30,6 +30,7 @@ enum ActionType {
   GenClangAttrSubjectMatchRulesParserStringSwitches,
   GenClangAttrImpl,
   GenClangAttrList,
+  GenClangAttrDocTable,
   GenClangAttrSubjectMatchRuleList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
@@ -115,6 +116,8 @@ cl::opt<ActionType> Action(
                    "Generate clang attribute implementations"),
         clEnumValN(GenClangAttrList, "gen-clang-attr-list",
                    "Generate a clang attribute list"),
+        clEnumValN(GenClangAttrDocTable, "gen-clang-attr-doc-table",
+                   "Generate a table of attribute documentation"),
         clEnumValN(GenClangAttrSubjectMatchRuleList,
                    "gen-clang-attr-subject-match-rule-list",
                    "Generate a clang attribute subject match rule list"),
@@ -280,6 +283,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
   case GenClangAttrList:
     EmitClangAttrList(Records, OS);
     break;
+  case GenClangAttrDocTable:
+    EmitClangAttrDocTable(Records, OS);
+    break;
   case GenClangAttrSubjectMatchRuleList:
     EmitClangAttrSubjectMatchRuleList(Records, OS);
     break;

diff  --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h
index bf40c7b1d18f8..fd8b9fcda20f0 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -61,6 +61,7 @@ void EmitClangAttrTextNodeDump(llvm::RecordKeeper &Records,
                                llvm::raw_ostream &OS);
 void EmitClangAttrNodeTraverse(llvm::RecordKeeper &Records,
                                llvm::raw_ostream &OS);
+void EmitClangAttrDocTable(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
 
 void EmitClangDiagsDefs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS,
                         const std::string &Component);


        


More information about the cfe-commits mailing list