mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 12:05:50 +00:00
Fix auto variable type deduction when auto is a pointer.
This commit is contained in:
parent
b79b98f464
commit
44153f94e8
@ -481,8 +481,7 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
|||||||
// (ie, Foo<A,B> => Foo<*,*>).
|
// (ie, Foo<A,B> => Foo<*,*>).
|
||||||
optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
||||||
clang::Cursor cursor) {
|
clang::Cursor cursor) {
|
||||||
clang::Cursor declaration =
|
clang::Cursor declaration = cursor.get_declaration();
|
||||||
cursor.get_type().strip_qualifiers().get_declaration();
|
|
||||||
declaration = declaration.template_specialization_to_template_definition();
|
declaration = declaration.template_specialization_to_template_definition();
|
||||||
std::string usr = declaration.get_usr();
|
std::string usr = declaration.get_usr();
|
||||||
if (usr != "")
|
if (usr != "")
|
||||||
|
@ -34,6 +34,10 @@ std::string Type::get_usr() const {
|
|||||||
return clang::Cursor(clang_getTypeDeclaration(cx_type)).get_usr();
|
return clang::Cursor(clang_getTypeDeclaration(cx_type)).get_usr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type Type::get_canonical() const {
|
||||||
|
return clang_getCanonicalType(cx_type);
|
||||||
|
}
|
||||||
|
|
||||||
Type Type::strip_qualifiers() const {
|
Type Type::strip_qualifiers() const {
|
||||||
// CXRefQualifierKind qualifiers = clang_Type_getCXXRefQualifier(cx_type)
|
// CXRefQualifierKind qualifiers = clang_Type_getCXXRefQualifier(cx_type)
|
||||||
switch (cx_type.kind) {
|
switch (cx_type.kind) {
|
||||||
@ -112,6 +116,18 @@ CXCursorKind Cursor::get_kind() const {
|
|||||||
return cx_cursor.kind;
|
return cx_cursor.kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cursor Cursor::get_declaration() const {
|
||||||
|
Type type = get_type();
|
||||||
|
|
||||||
|
// auto x = new Foo() will not be deduced to |Foo| if we do not use the
|
||||||
|
// canonical type. However, a canonical type will look past typedefs so we
|
||||||
|
// will not accurately report variables on typedefs if we always do this.
|
||||||
|
if (type.cx_type.kind == CXType_Auto)
|
||||||
|
type = type.get_canonical();
|
||||||
|
|
||||||
|
return type.strip_qualifiers().get_declaration();
|
||||||
|
}
|
||||||
|
|
||||||
Type Cursor::get_type() const {
|
Type Cursor::get_type() const {
|
||||||
return Type(clang_getCursorType(cx_cursor));
|
return Type(clang_getCursorType(cx_cursor));
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ class Type {
|
|||||||
CXCursor get_declaration() const;
|
CXCursor get_declaration() const;
|
||||||
std::string get_usr() const;
|
std::string get_usr() const;
|
||||||
std::string get_spelling() const;
|
std::string get_spelling() const;
|
||||||
|
Type get_canonical() const;
|
||||||
|
|
||||||
// Try to resolve this type and remove qualifies, ie, Foo* will become Foo
|
// Try to resolve this type and remove qualifies, ie, Foo* will become Foo
|
||||||
Type strip_qualifiers() const;
|
Type strip_qualifiers() const;
|
||||||
@ -46,6 +47,7 @@ class Cursor {
|
|||||||
bool operator!=(const Cursor& rhs) const;
|
bool operator!=(const Cursor& rhs) const;
|
||||||
|
|
||||||
CXCursorKind get_kind() const;
|
CXCursorKind get_kind() const;
|
||||||
|
Cursor get_declaration() const;
|
||||||
Type get_type() const;
|
Type get_type() const;
|
||||||
std::string get_spelling() const;
|
std::string get_spelling() const;
|
||||||
std::string get_display_name() const;
|
std::string get_display_name() const;
|
||||||
|
48
tests/vars/deduce_auto_type.cc
Normal file
48
tests/vars/deduce_auto_type.cc
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
class Foo {};
|
||||||
|
void f() {
|
||||||
|
auto x = new Foo();
|
||||||
|
auto* y = new Foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
OUTPUT:
|
||||||
|
{
|
||||||
|
"types": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:@S@Foo",
|
||||||
|
"short_name": "Foo",
|
||||||
|
"detailed_name": "Foo",
|
||||||
|
"definition_spelling": "1:7-1:10",
|
||||||
|
"definition_extent": "1:1-1:13",
|
||||||
|
"instances": [0, 1],
|
||||||
|
"uses": ["1:7-1:10", "3:16-3:19", "4:17-4:20"]
|
||||||
|
}],
|
||||||
|
"funcs": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:@F@f#",
|
||||||
|
"short_name": "f",
|
||||||
|
"detailed_name": "void f()",
|
||||||
|
"definition_spelling": "2:6-2:7",
|
||||||
|
"definition_extent": "2:1-5:2"
|
||||||
|
}],
|
||||||
|
"vars": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:deduce_auto_type.cc@29@F@f#@x",
|
||||||
|
"short_name": "x",
|
||||||
|
"detailed_name": "Foo * x",
|
||||||
|
"definition_spelling": "3:8-3:9",
|
||||||
|
"definition_extent": "3:3-3:21",
|
||||||
|
"variable_type": 0,
|
||||||
|
"uses": ["3:8-3:9"]
|
||||||
|
}, {
|
||||||
|
"id": 1,
|
||||||
|
"usr": "c:deduce_auto_type.cc@52@F@f#@y",
|
||||||
|
"short_name": "y",
|
||||||
|
"detailed_name": "Foo * y",
|
||||||
|
"definition_spelling": "4:9-4:10",
|
||||||
|
"definition_extent": "4:3-4:22",
|
||||||
|
"variable_type": 0,
|
||||||
|
"uses": ["4:9-4:10"]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
*/
|
50
tests/vars/type_instance_on_using_type.cc
Normal file
50
tests/vars/type_instance_on_using_type.cc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
struct S {};
|
||||||
|
using F = S;
|
||||||
|
void Foo() {
|
||||||
|
F a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Should we also add a usage to |S|?
|
||||||
|
|
||||||
|
/*
|
||||||
|
OUTPUT:
|
||||||
|
{
|
||||||
|
"types": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:@S@S",
|
||||||
|
"short_name": "S",
|
||||||
|
"detailed_name": "S",
|
||||||
|
"definition_spelling": "1:8-1:9",
|
||||||
|
"definition_extent": "1:1-1:12",
|
||||||
|
"uses": ["1:8-1:9", "2:11-2:12"]
|
||||||
|
}, {
|
||||||
|
"id": 1,
|
||||||
|
"usr": "c:@F",
|
||||||
|
"short_name": "F",
|
||||||
|
"detailed_name": "F",
|
||||||
|
"definition_spelling": "2:7-2:8",
|
||||||
|
"definition_extent": "2:1-2:12",
|
||||||
|
"alias_of": 0,
|
||||||
|
"instances": [0],
|
||||||
|
"uses": ["2:7-2:8", "4:3-4:4"]
|
||||||
|
}],
|
||||||
|
"funcs": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:@F@Foo#",
|
||||||
|
"short_name": "Foo",
|
||||||
|
"detailed_name": "void Foo()",
|
||||||
|
"definition_spelling": "3:6-3:9",
|
||||||
|
"definition_extent": "3:1-5:2"
|
||||||
|
}],
|
||||||
|
"vars": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:type_instance_on_using_type.cc@44@F@Foo#@a",
|
||||||
|
"short_name": "a",
|
||||||
|
"detailed_name": "F a",
|
||||||
|
"definition_spelling": "4:5-4:6",
|
||||||
|
"definition_extent": "4:3-4:6",
|
||||||
|
"variable_type": 1,
|
||||||
|
"uses": ["4:5-4:6"]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user