[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