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<*,*>).
|
||||
optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
||||
clang::Cursor cursor) {
|
||||
clang::Cursor declaration =
|
||||
cursor.get_type().strip_qualifiers().get_declaration();
|
||||
clang::Cursor declaration = cursor.get_declaration();
|
||||
declaration = declaration.template_specialization_to_template_definition();
|
||||
std::string usr = declaration.get_usr();
|
||||
if (usr != "")
|
||||
|
@ -34,6 +34,10 @@ std::string Type::get_usr() const {
|
||||
return clang::Cursor(clang_getTypeDeclaration(cx_type)).get_usr();
|
||||
}
|
||||
|
||||
Type Type::get_canonical() const {
|
||||
return clang_getCanonicalType(cx_type);
|
||||
}
|
||||
|
||||
Type Type::strip_qualifiers() const {
|
||||
// CXRefQualifierKind qualifiers = clang_Type_getCXXRefQualifier(cx_type)
|
||||
switch (cx_type.kind) {
|
||||
@ -112,6 +116,18 @@ CXCursorKind Cursor::get_kind() const {
|
||||
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 {
|
||||
return Type(clang_getCursorType(cx_cursor));
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class Type {
|
||||
CXCursor get_declaration() const;
|
||||
std::string get_usr() const;
|
||||
std::string get_spelling() const;
|
||||
Type get_canonical() const;
|
||||
|
||||
// Try to resolve this type and remove qualifies, ie, Foo* will become Foo
|
||||
Type strip_qualifiers() const;
|
||||
@ -46,6 +47,7 @@ class Cursor {
|
||||
bool operator!=(const Cursor& rhs) const;
|
||||
|
||||
CXCursorKind get_kind() const;
|
||||
Cursor get_declaration() const;
|
||||
Type get_type() const;
|
||||
std::string get_spelling() 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