// Enum conversion
-std::string getAccess(AccessSpecifier AS) {
- switch (AS) {
- case AccessSpecifier::AS_public:
- return "public";
- case AccessSpecifier::AS_protected:
- return "protected";
- case AccessSpecifier::AS_private:
- return "private";
- case AccessSpecifier::AS_none:
- return {};
- }
- llvm_unreachable("Unknown AccessSpecifier");
-}
-
std::string getTagType(TagTypeKind AS) {
switch (AS) {
case TagTypeKind::TTK_Class:
llvm::Expected<std::unique_ptr<Generator>>
findGeneratorByName(llvm::StringRef Format);
-std::string getAccess(AccessSpecifier AS);
-
std::string getTagType(TagTypeKind AS);
} // namespace doc
Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_UL));
auto &ULBody = Out.back();
for (const auto &M : Members) {
- std::string Access = getAccess(M.Access);
+ std::string Access = getAccessSpelling(M.Access).str();
if (Access != "")
Access = Access + " ";
auto LIBody = std::make_unique<TagNode>(HTMLTag::TAG_LI);
Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_P));
auto &FunctionHeader = Out.back();
- std::string Access = getAccess(I.Access);
+ std::string Access = getAccessSpelling(I.Access).str();
if (Access != "")
FunctionHeader->Children.emplace_back(
std::make_unique<TextNode>(Access + " "));
First = false;
}
writeHeader(I.Name, 3, OS);
- std::string Access = getAccess(I.Access);
+ std::string Access = getAccessSpelling(I.Access).str();
if (Access != "")
writeLine(genItalic(Access + " " + I.ReturnType.Type.Name + " " + I.Name +
"(" + Stream.str() + ")"),
if (!I.Members.empty()) {
writeHeader("Members", 2, OS);
for (const auto &Member : I.Members) {
- std::string Access = getAccess(Member.Access);
+ std::string Access = getAccessSpelling(Member.Access).str();
if (Access != "")
writeLine(Access + " " + Member.Type.Name + " " + Member.Name, OS);
else
HoverInfo HI;
const ASTContext &Ctx = D->getASTContext();
+ HI.AccessSpecifier = getAccessSpelling(D->getAccess()).str();
HI.NamespaceScope = getNamespaceScope(D);
if (!HI.NamespaceScope->empty())
HI.NamespaceScope->append("::");
ScopeComment = "// In namespace " +
llvm::StringRef(*NamespaceScope).rtrim(':').str() + '\n';
}
+ std::string DefinitionWithAccess = !AccessSpecifier.empty()
+ ? AccessSpecifier + ": " + Definition
+ : Definition;
// Note that we don't print anything for global namespace, to not annoy
// non-c++ projects or projects that are not making use of namespaces.
- Output.addCodeBlock(ScopeComment + Definition);
+ Output.addCodeBlock(ScopeComment + DefinitionWithAccess);
}
return Output;
}
/// Source code containing the definition of the symbol.
std::string Definition;
+ /// Access specifier for declarations inside class/struct/unions, empty for
+ /// others.
+ std::string AccessSpecifier;
/// Pretty-printed variable type.
/// Set only for variables.
llvm::Optional<std::string> Type;
#include "TestIndex.h"
#include "TestTU.h"
#include "index/MemIndex.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Index/IndexSymbol.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
HI.Type = "char";
HI.Offset = 0;
HI.Size = 1;
+ HI.AccessSpecifier = "public";
}},
// Local to class method.
{R"cpp(
HI.Type = "char";
HI.Offset = 0;
HI.Size = 1;
+ HI.AccessSpecifier = "public";
}},
// Struct definition shows size.
{R"cpp(
HI.Kind = index::SymbolKind::Constructor;
HI.Definition = "X()";
HI.Parameters.emplace();
+ HI.AccessSpecifier = "public";
}},
{"class X { [[^~]]X(); };", // FIXME: Should be [[~X]]()
[](HoverInfo &HI) {
HI.Kind = index::SymbolKind::Destructor;
HI.Definition = "~X()";
HI.Parameters.emplace();
+ HI.AccessSpecifier = "private";
}},
{"class X { [[op^erator]] int(); };",
[](HoverInfo &HI) {
HI.Kind = index::SymbolKind::ConversionFunction;
HI.Definition = "operator int()";
HI.Parameters.emplace();
+ HI.AccessSpecifier = "private";
}},
{"class X { operator [[^X]](); };",
[](HoverInfo &HI) {
HI.NamespaceScope = "";
HI.LocalScope = "Add<1, 2>::";
HI.Value = "3";
+ HI.AccessSpecifier = "public";
}},
{R"cpp(
constexpr int answer() { return 40 + 2; }
HI.Definition = "typename T = int";
HI.LocalScope = "foo::";
HI.Type = "typename";
+ HI.AccessSpecifier = "public";
}},
{// TemplateTemplate Type Parameter
R"cpp(
HI.Definition = "template <typename> class T";
HI.LocalScope = "foo::";
HI.Type = "template <typename> class";
+ HI.AccessSpecifier = "public";
}},
{// NonType Template Parameter
R"cpp(
HI.Definition = "int T = 5";
HI.LocalScope = "foo::";
HI.Type = "int";
+ HI.AccessSpecifier = "public";
}},
{// Getter
HI.Type = "float ()";
HI.ReturnType = "float";
HI.Parameters.emplace();
+ HI.AccessSpecifier = "public";
}},
{// Setter
R"cpp(
HI.Parameters->emplace_back();
HI.Parameters->back().Type = "float";
HI.Parameters->back().Name = "v";
+ HI.AccessSpecifier = "public";
}},
{// Setter (builder)
R"cpp(
HI.Parameters->emplace_back();
HI.Parameters->back().Type = "float";
HI.Parameters->back().Name = "v";
+ HI.AccessSpecifier = "public";
}},
};
for (const auto &Case : Cases) {
EXPECT_EQ(H->Value, Expected.Value);
EXPECT_EQ(H->Size, Expected.Size);
EXPECT_EQ(H->Offset, Expected.Offset);
+ EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
}
}
// In test::Bar
def)",
},
- };
+ {
+ [](HoverInfo &HI) {
+ HI.Kind = index::SymbolKind::Field;
+ HI.AccessSpecifier = "public";
+ HI.Name = "foo";
+ HI.LocalScope = "test::Bar::";
+ HI.Definition = "def";
+ },
+ R"(field foo
+
+// In test::Bar
+public: def)",
+ },
+ {
+ [](HoverInfo &HI) {
+ HI.Definition = "int method()";
+ HI.AccessSpecifier = "protected";
+ HI.Kind = index::SymbolKind::InstanceMethod;
+ HI.NamespaceScope = "";
+ HI.LocalScope = "cls<int>::";
+ HI.Name = "method";
+ HI.Parameters.emplace();
+ HI.ReturnType = "int";
+ HI.Type = "int ()";
+ },
+ R"(instance-method method
+
+→ int
+
+// In cls<int>
+protected: int method())",
+ },
+ {
+ [](HoverInfo &HI) {
+ HI.Kind = index::SymbolKind::Union;
+ HI.AccessSpecifier = "private";
+ HI.Name = "foo";
+ HI.NamespaceScope = "ns1::";
+ HI.Definition = "union foo {}";
+ },
+ R"(union foo
+
+// In namespace ns1
+private: union foo {})",
+ }};
for (const auto &C : Cases) {
HoverInfo HI;
};
llvm::StringRef getParameterABISpelling(ParameterABI kind);
+
+ inline llvm::StringRef getAccessSpelling(AccessSpecifier AS) {
+ switch (AS) {
+ case AccessSpecifier::AS_public:
+ return "public";
+ case AccessSpecifier::AS_protected:
+ return "protected";
+ case AccessSpecifier::AS_private:
+ return "private";
+ case AccessSpecifier::AS_none:
+ return {};
+ }
+ llvm_unreachable("Unknown AccessSpecifier");
+ }
} // end namespace clang
#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
}
void DeclPrinter::Print(AccessSpecifier AS) {
- switch(AS) {
- case AS_none: llvm_unreachable("No access specifier!");
- case AS_public: Out << "public"; break;
- case AS_protected: Out << "protected"; break;
- case AS_private: Out << "private"; break;
- }
+ const auto AccessSpelling = getAccessSpelling(AS);
+ if (AccessSpelling.empty())
+ llvm_unreachable("No access specifier!");
+ Out << AccessSpelling;
}
void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl,
#include "clang/AST/JSONNodeDumper.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/StringSwitch.h"
#undef FIELD2
std::string JSONNodeDumper::createAccessSpecifier(AccessSpecifier AS) {
- switch (AS) {
- case AS_none: return "none";
- case AS_private: return "private";
- case AS_protected: return "protected";
- case AS_public: return "public";
- }
- llvm_unreachable("Unknown access specifier");
+ const auto AccessSpelling = getAccessSpelling(AS);
+ if (AccessSpelling.empty())
+ return "none";
+ return AccessSpelling.str();
}
llvm::json::Object
#include "clang/AST/LocInfoType.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
using namespace clang;
}
void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
- switch (AS) {
- case AS_none:
- break;
- case AS_public:
- OS << "public";
- break;
- case AS_protected:
- OS << "protected";
- break;
- case AS_private:
- OS << "private";
- break;
- }
+ const auto AccessSpelling = getAccessSpelling(AS);
+ if (AccessSpelling.empty())
+ return;
+ OS << AccessSpelling;
}
void TextNodeDumper::dumpCleanupObject(