[index] Introduce SymbolSubKind for reporting language-specific details.

Initially reports if a constructor symbol is a copy or move constructor.

llvm-svn: 291409
This commit is contained in:
Argyrios Kyrtzidis 2017-01-08 23:21:35 +00:00
parent 796c1d9b54
commit e24f5e204b
4 changed files with 39 additions and 1 deletions

View File

@ -59,6 +59,13 @@ enum class SymbolLanguage {
CXX, CXX,
}; };
/// Language specific sub-kinds.
enum class SymbolSubKind {
None,
CXXCopyConstructor,
CXXMoveConstructor,
};
/// Set of properties that provide additional info about a symbol. /// Set of properties that provide additional info about a symbol.
enum class SymbolProperty : uint8_t { enum class SymbolProperty : uint8_t {
Generic = 1 << 0, Generic = 1 << 0,
@ -107,6 +114,7 @@ struct SymbolRelation {
struct SymbolInfo { struct SymbolInfo {
SymbolKind Kind; SymbolKind Kind;
SymbolSubKind SubKind;
SymbolPropertySet Properties; SymbolPropertySet Properties;
SymbolLanguage Lang; SymbolLanguage Lang;
}; };
@ -121,6 +129,7 @@ void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS);
bool printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS); bool printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS);
StringRef getSymbolKindString(SymbolKind K); StringRef getSymbolKindString(SymbolKind K);
StringRef getSymbolSubKindString(SymbolSubKind K);
StringRef getSymbolLanguageString(SymbolLanguage K); StringRef getSymbolLanguageString(SymbolLanguage K);
void applyForEachSymbolProperty(SymbolPropertySet Props, void applyForEachSymbolProperty(SymbolPropertySet Props,

View File

@ -53,6 +53,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
assert(D); assert(D);
SymbolInfo Info; SymbolInfo Info;
Info.Kind = SymbolKind::Unknown; Info.Kind = SymbolKind::Unknown;
Info.SubKind = SymbolSubKind::None;
Info.Properties = SymbolPropertySet(); Info.Properties = SymbolPropertySet();
Info.Lang = SymbolLanguage::C; Info.Lang = SymbolLanguage::C;
@ -183,10 +184,16 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
Info.Kind = SymbolKind::NamespaceAlias; Info.Kind = SymbolKind::NamespaceAlias;
Info.Lang = SymbolLanguage::CXX; Info.Lang = SymbolLanguage::CXX;
break; break;
case Decl::CXXConstructor: case Decl::CXXConstructor: {
Info.Kind = SymbolKind::Constructor; Info.Kind = SymbolKind::Constructor;
Info.Lang = SymbolLanguage::CXX; Info.Lang = SymbolLanguage::CXX;
auto *CD = cast<CXXConstructorDecl>(D);
if (CD->isCopyConstructor())
Info.SubKind = SymbolSubKind::CXXCopyConstructor;
else if (CD->isMoveConstructor())
Info.SubKind = SymbolSubKind::CXXMoveConstructor;
break; break;
}
case Decl::CXXDestructor: case Decl::CXXDestructor:
Info.Kind = SymbolKind::Destructor; Info.Kind = SymbolKind::Destructor;
Info.Lang = SymbolLanguage::CXX; Info.Lang = SymbolLanguage::CXX;
@ -363,6 +370,15 @@ StringRef index::getSymbolKindString(SymbolKind K) {
llvm_unreachable("invalid symbol kind"); llvm_unreachable("invalid symbol kind");
} }
StringRef index::getSymbolSubKindString(SymbolSubKind K) {
switch (K) {
case SymbolSubKind::None: return "<none>";
case SymbolSubKind::CXXCopyConstructor: return "cxx-copy-ctor";
case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
}
llvm_unreachable("invalid symbol subkind");
}
StringRef index::getSymbolLanguageString(SymbolLanguage K) { StringRef index::getSymbolLanguageString(SymbolLanguage K) {
switch (K) { switch (K) {
case SymbolLanguage::C: return "C"; case SymbolLanguage::C: return "C";

View File

@ -1,5 +1,16 @@
// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s // RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Def | rel: 0
class Cls {
// CHECK: [[@LINE+2]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
// CHECK-NEXT: RelChild | Cls | c:@S@Cls
Cls(int x);
// CHECK: [[@LINE+1]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S@Cls@F@Cls#&1$@S@Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1
Cls(const Cls &);
// CHECK: [[@LINE+1]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S@Cls@F@Cls#&&$@S@Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1
Cls(Cls &&);
};
template <typename TemplArg> template <typename TemplArg>
class TemplCls { class TemplCls {
// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Def | rel: 0 // CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Def | rel: 0

View File

@ -166,6 +166,8 @@ static bool printSourceSymbols(ArrayRef<const char *> Args) {
static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) { static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) {
OS << getSymbolKindString(SymInfo.Kind); OS << getSymbolKindString(SymInfo.Kind);
if (SymInfo.SubKind != SymbolSubKind::None)
OS << '/' << getSymbolSubKindString(SymInfo.SubKind);
if (SymInfo.Properties) { if (SymInfo.Properties) {
OS << '('; OS << '(';
printSymbolProperties(SymInfo.Properties, OS); printSymbolProperties(SymInfo.Properties, OS);