Fix auto variable type deduction when auto is a pointer.

This commit is contained in:
Jacob Dufault 2017-05-20 17:19:32 -07:00
parent b79b98f464
commit 44153f94e8
5 changed files with 117 additions and 2 deletions

View File

@ -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 != "")

View File

@ -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));
} }

View File

@ -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;

View 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"]
}]
}
*/

View 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"]
}]
}
*/