This commit is contained in:
Jacob Dufault 2017-02-18 13:18:08 -08:00
parent 0718435400
commit 46cec6f083
39 changed files with 678 additions and 72 deletions

View File

@ -174,7 +174,7 @@ std::string Cursor::get_comments() const {
} }
std::string Cursor::ToString() const { std::string Cursor::ToString() const {
return get_spelling() + " " + clang::ToString(get_kind()); return clang::ToString(get_kind()) + " " + get_spelling();
} }
} // namespace clang } // namespace clang

121
main.cpp
View File

@ -52,6 +52,8 @@ template<typename T>
struct Ref { struct Ref {
LocalId<T> id; LocalId<T> id;
clang::SourceLocation loc; clang::SourceLocation loc;
Ref(LocalId<T> id, clang::SourceLocation loc) : id(id), loc(loc) {}
}; };
using TypeRef = Ref<TypeDef>; using TypeRef = Ref<TypeDef>;
using FuncRef = Ref<FuncDef>; using FuncRef = Ref<FuncDef>;
@ -398,11 +400,6 @@ std::string ParsingDatabase::ToString(bool for_test) {
writer.String("declaration"); writer.String("declaration");
WriteLocation(writer, def.declaration); WriteLocation(writer, def.declaration);
if (def.initializations.size() == 0) {
writer.EndObject();
continue;
}
writer.String("initializations"); writer.String("initializations");
WriteLocationArray(writer, def.initializations); WriteLocationArray(writer, def.initializations);
@ -491,7 +488,8 @@ struct NamespaceStack {
void Push(const std::string& ns); void Push(const std::string& ns);
void Pop(); void Pop();
std::string ComputeQualifiedPrefix(); std::string ComputeQualifiedName(
ParsingDatabase* db, std::optional<TypeId> declaring_type, std::string short_name);
static NamespaceStack kEmpty; static NamespaceStack kEmpty;
}; };
@ -505,10 +503,17 @@ void NamespaceStack::Pop() {
stack.pop_back(); stack.pop_back();
} }
std::string NamespaceStack::ComputeQualifiedPrefix() { std::string NamespaceStack::ComputeQualifiedName(
ParsingDatabase* db, std::optional<TypeId> declaring_type, std::string short_name) {
if (declaring_type) {
TypeDef* def = db->Resolve(declaring_type.value());
return def->qualified_name + "::" + short_name;
}
std::string result; std::string result;
for (const std::string& ns : stack) for (const std::string& ns : stack)
result += ns + "::"; result += ns + "::";
result += short_name;
return result; return result;
} }
@ -520,10 +525,9 @@ std::string NamespaceStack::ComputeQualifiedPrefix() {
std::optional<TypeId> ResolveDeclaringType(CXCursorKind kind, ParsingDatabase* db, const clang::Cursor& cursor, std::optional<TypeId> declaring_type) { std::optional<TypeId> ResolveDeclaringType(CXCursorKind kind, ParsingDatabase* db, const clang::Cursor& cursor, std::optional<TypeId> declaring_type) {
// Resolve the declaring type for out-of-line method definitions. // Resolve the declaring type for out-of-line method definitions.
if (!declaring_type && cursor.get_kind() == kind) { if (!declaring_type) {
clang::Cursor parent = cursor.get_semantic_parent(); clang::Cursor parent = cursor.get_semantic_parent();
switch (parent.get_kind()) { switch (parent.get_kind()) {
case CXCursor_ClassDecl: case CXCursor_ClassDecl:
@ -556,7 +560,7 @@ std::optional<TypeId> ResolveDeclaringType(CXCursorKind kind, ParsingDatabase* d
clang::VisiterResult DumpVisitor(clang::Cursor cursor, clang::Cursor parent, int* level) { clang::VisiterResult DumpVisitor(clang::Cursor cursor, clang::Cursor parent, int* level) {
for (int i = 0; i < *level; ++i) for (int i = 0; i < *level; ++i)
std::cout << " "; std::cout << " ";
std::cout << cursor.get_spelling() << " " << clang::ToString(cursor.get_kind()) << std::endl; std::cout << clang::ToString(cursor.get_kind()) << " " << cursor.get_spelling() << std::endl;
*level += 1; *level += 1;
cursor.VisitChildren(&DumpVisitor, level); cursor.VisitChildren(&DumpVisitor, level);
@ -577,7 +581,7 @@ void Dump(clang::Cursor cursor) {
void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, std::optional<TypeId> declaring_type) { void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, std::optional<TypeId> declaring_type) {
Dump(var); //Dump(var);
VarId var_id = db->ToVarId(var.get_usr()); VarId var_id = db->ToVarId(var.get_usr());
@ -587,7 +591,8 @@ void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, s
// instance alive. // instance alive.
VarDef* var_def = db->Resolve(var_id); VarDef* var_def = db->Resolve(var_id);
var_def->short_name = var.get_spelling(); var_def->short_name = var.get_spelling();
var_def->qualified_name = ns->ComputeQualifiedPrefix() + var_def->short_name; var_def->qualified_name =
ns->ComputeQualifiedName(db, declaring_type, var_def->short_name);
if (declaring_type && !var_def->declaration) { if (declaring_type && !var_def->declaration) {
db->Resolve(declaring_type.value())->vars.push_back(var_id); db->Resolve(declaring_type.value())->vars.push_back(var_id);
@ -599,7 +604,14 @@ void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, s
var_def->declaration = var.get_source_location(); var_def->declaration = var.get_source_location();
return; return;
} }
// If we're a definition and there hasn't been a forward decl, just assign
// declaration location to definition location.
else if (!var_def->declaration) {
var_def->declaration = var.get_source_location();
}
// TODO: Figure out how to scan initializations properly. We probably need
// to scan for assignment statement, or definition+ctor.
var_def->initializations.push_back(var.get_source_location()); var_def->initializations.push_back(var.get_source_location());
var_def->variable_type = db->ToTypeId(var.get_type().get_usr()); var_def->variable_type = db->ToTypeId(var.get_type().get_usr());
} }
@ -608,36 +620,69 @@ void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, s
// |func_id| is the function definition that is currently being processed.
void InsertReference(ParsingDatabase* db, FuncId func_id, clang::Cursor referencer) {
clang::Cursor referenced = referencer.get_referenced();
switch (referenced.get_kind()) {
case CXCursor_FunctionDecl:
{
FuncId referenced_id = db->ToFuncId(referenced.get_usr());
clang::SourceLocation loc = referencer.get_source_location();
FuncDef* func_def = db->Resolve(func_id);
FuncDef* referenced_def = db->Resolve(referenced_id);
func_def->callees.push_back(FuncRef(referenced_id, loc));
referenced_def->callers.push_back(FuncRef(func_id, loc));
referenced_def->uses.push_back(loc);
break;
}
default:
std::cerr << "Unhandled reference from " << referencer.ToString() << " to "
<< referenced.ToString() << std::endl;
break;
}
}
struct FuncDefinitionParam { struct FuncDefinitionParam {
ParsingDatabase* db; ParsingDatabase* db;
NamespaceStack* ns; NamespaceStack* ns;
FuncDefinitionParam(ParsingDatabase* db, NamespaceStack* ns) FuncId func_id;
: db(db), ns(ns) {} FuncDefinitionParam(ParsingDatabase* db, NamespaceStack* ns, FuncId func_id)
: db(db), ns(ns), func_id(func_id) {}
}; };
clang::VisiterResult VisitFuncDefinition(clang::Cursor cursor, clang::Cursor parent, FuncDefinitionParam* param) { clang::VisiterResult VisitFuncDefinition(clang::Cursor cursor, clang::Cursor parent, FuncDefinitionParam* param) {
//std::cout << "VistFunc got " << cursor.ToString() << std::endl; //std::cout << "VistFunc got " << cursor.ToString() << std::endl;
switch (cursor.get_kind()) { switch (cursor.get_kind()) {
// TODO: Maybe we should default to recurse?
/*
case CXCursor_CompoundStmt: case CXCursor_CompoundStmt:
case CXCursor_DeclStmt: case CXCursor_DeclStmt:
case CXCursor_CallExpr:
case CXCursor_UnexposedExpr:
case CXCursor_UnaryExpr:
return clang::VisiterResult::Recurse; return clang::VisiterResult::Recurse;
*/
case CXCursor_DeclRefExpr:
InsertReference(param->db, param->func_id, cursor);
break;
case CXCursor_VarDecl: case CXCursor_VarDecl:
case CXCursor_ParmDecl: case CXCursor_ParmDecl:
HandleVarDecl(param->db, param->ns, cursor, std::nullopt); HandleVarDecl(param->db, param->ns, cursor, std::nullopt);
return clang::VisiterResult::Continue; return clang::VisiterResult::Recurse;
case CXCursor_ReturnStmt: case CXCursor_ReturnStmt:
return clang::VisiterResult::Continue; return clang::VisiterResult::Recurse;
default: default:
std::cerr << "Unhandled VisitFuncDefinition kind " << clang::ToString(cursor.get_kind()) << std::endl; //std::cerr << "Unhandled VisitFuncDefinition kind " << clang::ToString(cursor.get_kind()) << std::endl;
return clang::VisiterResult::Continue; return clang::VisiterResult::Recurse;
} }
} }
@ -663,11 +708,8 @@ void HandleFunc(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor func, std
FuncDef* func_def = db->Resolve(func_id); FuncDef* func_def = db->Resolve(func_id);
func_def->short_name = func.get_spelling(); func_def->short_name = func.get_spelling();
std::string type_name;
if (declaring_type)
type_name = db->Resolve(declaring_type.value())->short_name + "::";
func_def->qualified_name = func_def->qualified_name =
ns->ComputeQualifiedPrefix() + type_name + func_def->short_name; ns->ComputeQualifiedName(db, declaring_type, func_def->short_name);
if (declaring_type && !func_def->declaration) { if (declaring_type && !func_def->declaration) {
db->Resolve(declaring_type.value())->funcs.push_back(func_id); db->Resolve(declaring_type.value())->funcs.push_back(func_id);
@ -699,8 +741,8 @@ void HandleFunc(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor func, std
//clang::Type return_type_1 = func.get_type().get_result(); //clang::Type return_type_1 = func.get_type().get_result();
//clang::Type return_type_2 = clang_getCursorResultType(func.cx_cursor); //clang::Type return_type_2 = clang_getCursorResultType(func.cx_cursor);
Dump(func); //Dump(func);
FuncDefinitionParam funcDefinitionParam(db, &NamespaceStack::kEmpty); FuncDefinitionParam funcDefinitionParam(db, &NamespaceStack::kEmpty, func_id);
func.VisitChildren(&VisitFuncDefinition, &funcDefinitionParam); func.VisitChildren(&VisitFuncDefinition, &funcDefinitionParam);
//CXType return_type = clang_getResultType(func.get_type()); //CXType return_type = clang_getResultType(func.get_type());
@ -735,6 +777,7 @@ clang::VisiterResult VisitClassDecl(clang::Cursor cursor, clang::Cursor parent,
break; break;
case CXCursor_FieldDecl: case CXCursor_FieldDecl:
case CXCursor_VarDecl:
HandleVarDecl(param->db, param->ns, cursor, param->active_type); HandleVarDecl(param->db, param->ns, cursor, param->active_type);
break; break;
@ -747,21 +790,23 @@ clang::VisiterResult VisitClassDecl(clang::Cursor cursor, clang::Cursor parent,
} }
void HandleClassDecl(clang::Cursor cursor, ParsingDatabase* db, NamespaceStack* ns) { void HandleClassDecl(clang::Cursor cursor, ParsingDatabase* db, NamespaceStack* ns) {
TypeId id = db->ToTypeId(cursor.get_usr()); TypeId func_id = db->ToTypeId(cursor.get_usr());
TypeDef* def = db->Resolve(id); TypeDef* func_def = db->Resolve(func_id);
def->short_name = cursor.get_spelling(); func_def->short_name = cursor.get_spelling();
def->qualified_name = ns->ComputeQualifiedPrefix() + cursor.get_spelling(); // TODO: Support nested classes (pass in declaring type insteaad of nullopt!)
func_def->qualified_name =
ns->ComputeQualifiedName(db, std::nullopt, func_def->short_name);
if (!cursor.is_definition()) { if (!cursor.is_definition()) {
if (!def->declaration) if (!func_def->declaration)
def->declaration = cursor.get_source_location(); func_def->declaration = cursor.get_source_location();
return; return;
} }
def->definition = cursor.get_source_location(); func_def->definition = cursor.get_source_location();
ClassDeclParam classDeclParam(db, ns, id); ClassDeclParam classDeclParam(db, ns, func_id);
cursor.VisitChildren(&VisitClassDecl, &classDeclParam); cursor.VisitChildren(&VisitClassDecl, &classDeclParam);
} }
@ -797,6 +842,10 @@ clang::VisiterResult VisitFile(clang::Cursor cursor, clang::Cursor parent, FileP
HandleFunc(param->db, param->ns, cursor, std::nullopt); HandleFunc(param->db, param->ns, cursor, std::nullopt);
break; break;
case CXCursor_VarDecl:
HandleVarDecl(param->db, param->ns, cursor, std::nullopt);
break;
default: default:
std::cerr << "Unhandled VisitFile kind " << clang::ToString(cursor.get_kind()) << std::endl; std::cerr << "Unhandled VisitFile kind " << clang::ToString(cursor.get_kind()) << std::endl;
break; break;
@ -821,9 +870,9 @@ ParsingDatabase Parse(std::string filename) {
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/); clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
clang::TranslationUnit tu(index, filename, args); clang::TranslationUnit tu(index, filename, args);
//std::cout << "Start document dump" << std::endl; std::cout << "Start document dump" << std::endl;
//Dump(tu.document_cursor()); Dump(tu.document_cursor());
//std::cout << "Done document dump" << std::endl << std::endl; std::cout << "Done document dump" << std::endl << std::endl;
ParsingDatabase db; ParsingDatabase db;
NamespaceStack ns; NamespaceStack ns;
@ -856,7 +905,7 @@ void Write(const std::vector<std::string>& strs) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
for (std::string path : GetFilesInFolder("tests")) { for (std::string path : GetFilesInFolder("tests")) {
// TODO: Fix all existing tests. // TODO: Fix all existing tests.
//if (path != "tests/vars/class_member.cc") continue; if (path != "tests/usage/func_usage_addr_func.cc") continue;
// Parse expected output from the test, parse it into JSON document. // Parse expected output from the test, parse it into JSON document.
std::string expected_output; std::string expected_output;

8
tests/_empty_test.cc Normal file
View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,17 @@
namespace {
void foo();
}
/*
OUTPUT:
{
"types": [],
"functions": [{
"id": 0,
"short_name": "foo",
"qualified_name": "::foo",
"declaration": "tests/namespaces/anonymous_function.cc:2:6"
}],
"variables": []
}
*/

View File

@ -10,7 +10,7 @@ OUTPUT:
"id": 0, "id": 0,
"short_name": "foo", "short_name": "foo",
"qualified_name": "hello::foo", "qualified_name": "hello::foo",
"declaration": "tests/function_declaration_in_namespace.cc:2:6" "declaration": "tests/namespaces/function_declaration.cc:2:6"
}], }],
"variables": [] "variables": []
} }

View File

@ -11,7 +11,7 @@ OUTPUT:
"short_name": "foo", "short_name": "foo",
"qualified_name": "hello::foo", "qualified_name": "hello::foo",
"declaration": null, "declaration": null,
"definition": "tests/function_definition_in_namespace.cc:2:6", "definition": "tests/namespaces/function_definition.cc:2:6",
"declaring_type": null, "declaring_type": null,
"base": null, "base": null,
"derived": [], "derived": [],

View File

@ -12,7 +12,7 @@ OUTPUT:
"short_name": "Foo", "short_name": "Foo",
"qualified_name": "hello::Foo", "qualified_name": "hello::Foo",
"declaration": null, "declaration": null,
"definition": "tests/method_declaration_in_namespace.cc:2:7", "definition": "tests/namespaces/method_declaration.cc:2:7",
"parents": [], "parents": [],
"derived": [], "derived": [],
"types": [], "types": [],
@ -24,7 +24,7 @@ OUTPUT:
"id": 0, "id": 0,
"short_name": "foo", "short_name": "foo",
"qualified_name": "hello::Foo::foo", "qualified_name": "hello::Foo::foo",
"declaration": "tests/method_declaration_in_namespace.cc:3:8", "declaration": "tests/namespaces/method_declaration.cc:3:8",
"declaring_type": 0 "declaring_type": 0
}], }],
"variables": [] "variables": []

View File

@ -14,7 +14,7 @@ OUTPUT:
"short_name": "Foo", "short_name": "Foo",
"qualified_name": "hello::Foo", "qualified_name": "hello::Foo",
"declaration": null, "declaration": null,
"definition": "tests/method_definition_in_namespace.cc:2:7", "definition": "tests/namespaces/method_definition.cc:2:7",
"parents": [], "parents": [],
"derived": [], "derived": [],
"types": [], "types": [],
@ -26,8 +26,8 @@ OUTPUT:
"id": 0, "id": 0,
"short_name": "foo", "short_name": "foo",
"qualified_name": "hello::Foo::foo", "qualified_name": "hello::Foo::foo",
"declaration": "tests/method_definition_in_namespace.cc:3:8", "declaration": "tests/namespaces/method_definition.cc:3:8",
"definition": "tests/method_definition_in_namespace.cc:6:11", "definition": "tests/namespaces/method_definition.cc:6:11",
"declaring_type": 0, "declaring_type": 0,
"base": null, "base": null,
"derived": [], "derived": [],

View File

@ -12,7 +12,7 @@ OUTPUT:
"short_name": "Foo", "short_name": "Foo",
"qualified_name": "hello::Foo", "qualified_name": "hello::Foo",
"declaration": null, "declaration": null,
"definition": "tests/method_inline_declaration_in_namespace.cc:2:7", "definition": "tests/namespaces/method_inline_declaration.cc:2:7",
"parents": [], "parents": [],
"derived": [], "derived": [],
"types": [], "types": [],
@ -25,7 +25,7 @@ OUTPUT:
"short_name": "foo", "short_name": "foo",
"qualified_name": "hello::Foo::foo", "qualified_name": "hello::Foo::foo",
"declaration": null, "declaration": null,
"definition": "tests/method_inline_declaration_in_namespace.cc:3:8", "definition": "tests/namespaces/method_inline_declaration.cc:3:8",
"declaring_type": 0, "declaring_type": 0,
"base": null, "base": null,
"derived": [], "derived": [],

View File

@ -0,0 +1,79 @@
void consume(void*) {}
void used() {}
void user() {
auto x = &used;
consume(&used);
}
/*
OUTPUT:
{
"types": [{
"id": 0,
"short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [{
"id": 0,
"short_name": "consume",
"qualified_name": "consume",
"declaration": null,
"definition": "tests/usage/func_usage_addr_func.cc:1:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": ["2@tests/usage/func_usage_addr_func.cc:7:3"],
"callees": [],
"uses": ["tests/usage/func_usage_addr_func.cc:7:3"]
}, {
"id": 1,
"short_name": "used",
"qualified_name": "used",
"declaration": null,
"definition": "tests/usage/func_usage_addr_func.cc:3:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": ["2@tests/usage/func_usage_addr_func.cc:6:13", "2@tests/usage/func_usage_addr_func.cc:7:12"],
"callees": [],
"uses": ["tests/usage/func_usage_addr_func.cc:6:13", "tests/usage/func_usage_addr_func.cc:7:12"]
}, {
"id": 2,
"short_name": "user",
"qualified_name": "user",
"declaration": null,
"definition": "tests/usage/func_usage_addr_func.cc:5:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": [],
"callees": ["1@tests/usage/func_usage_addr_func.cc:6:13", "0@tests/usage/func_usage_addr_func.cc:7:3", "1@tests/usage/func_usage_addr_func.cc:7:12"],
"uses": []
}],
"variables": [{
"id": 0,
"short_name": "",
"qualified_name": "",
"declaration": "tests/usage/func_usage_addr_func.cc:1:19",
"initializations": ["tests/usage/func_usage_addr_func.cc:1:19"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}, {
"id": 1,
"short_name": "x",
"qualified_name": "x",
"declaration": "tests/usage/func_usage_addr_func.cc:6:8",
"initializations": ["tests/usage/func_usage_addr_func.cc:6:8"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}]
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,8 @@
/*
OUTPUT:
{
"types": [],
"functions": [],
"variables": []
}
*/

View File

@ -4,8 +4,34 @@ class Foo {
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"id": 0,
"short_name": "Foo",
"qualified_name": "Foo",
"declaration": null,
"definition": "tests/vars/class_member.cc:1:7",
"parents": [],
"derived": [],
"types": [],
"funcs": [],
"vars": [0],
"uses": []
}, {
"id": 1,
"short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [], "functions": [],
"variables": [] "variables": [{
"id": 0,
"short_name": "member",
"qualified_name": "Foo::member",
"declaration": "tests/vars/class_member.cc:2:7",
"initializations": ["tests/vars/class_member.cc:2:7"],
"variable_type": 1,
"declaring_type": 0,
"uses": []
}]
} }
*/ */

View File

@ -1,8 +1,38 @@
class Foo {
static int member;
};
int Foo::member = 0;
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"functions": [], "id": 0,
"variables": [] "short_name": "Foo",
"qualified_name": "Foo",
"declaration": null,
"definition": "tests/vars/class_static_member.cc:1:7",
"parents": [],
"derived": [],
"types": [],
"funcs": [],
"vars": [0],
"uses": []
}, {
"id": 1,
"short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [],
"variables": [{
"id": 0,
"short_name": "member",
"qualified_name": "Foo::member",
"declaration": "tests/vars/class_static_member.cc:2:14",
"initializations": ["tests/vars/class_static_member.cc:4:10"],
"variable_type": 1,
"declaring_type": 0,
"uses": []
}]
} }
*/ */

View File

@ -1,8 +1,32 @@
class Foo {
static int member;
};
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"functions": [], "id": 0,
"variables": [] "short_name": "Foo",
"qualified_name": "Foo",
"declaration": null,
"definition": "tests/vars/class_static_member_decl_only.cc:1:7",
"parents": [],
"derived": [],
"types": [],
"funcs": [],
"vars": [0],
"uses": []
}],
"functions": [],
"variables": [{
"id": 0,
"short_name": "member",
"qualified_name": "Foo::member",
"declaration": "tests/vars/class_static_member_decl_only.cc:2:14",
"initializations": [],
"variable_type": null,
"declaring_type": 0,
"uses": []
}]
} }
*/ */

View File

@ -1,8 +1,38 @@
void foo() {
int a;
}
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"functions": [], "id": 0,
"variables": [] "short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [{
"id": 0,
"short_name": "foo",
"qualified_name": "foo",
"declaration": null,
"definition": "tests/vars/function_local.cc:1:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": [],
"callees": [],
"uses": []
}],
"variables": [{
"id": 0,
"short_name": "a",
"qualified_name": "a",
"declaration": "tests/vars/function_local.cc:2:7",
"initializations": ["tests/vars/function_local.cc:2:7"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}]
} }
*/ */

View File

@ -1,8 +1,45 @@
void foo(int p0, int p1) {}
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"functions": [], "id": 0,
"variables": [] "short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [{
"id": 0,
"short_name": "foo",
"qualified_name": "foo",
"declaration": null,
"definition": "tests/vars/function_param.cc:1:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": [],
"callees": [],
"uses": []
}],
"variables": [{
"id": 0,
"short_name": "p0",
"qualified_name": "p0",
"declaration": "tests/vars/function_param.cc:1:14",
"initializations": ["tests/vars/function_param.cc:1:14"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}, {
"id": 1,
"short_name": "p1",
"qualified_name": "p1",
"declaration": "tests/vars/function_param.cc:1:22",
"initializations": ["tests/vars/function_param.cc:1:22"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}]
} }
*/ */

View File

@ -0,0 +1,48 @@
void foo(int, int) {}
/*
// TODO: We should probably not emit variables for unnamed variables. But we
// still need to emit reference information.
OUTPUT:
{
"types": [{
"id": 0,
"short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [{
"id": 0,
"short_name": "foo",
"qualified_name": "foo",
"declaration": null,
"definition": "tests/vars/function_param.cc:1:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": [],
"callees": [],
"uses": []
}],
"variables": [{
"id": 0,
"short_name": "p0",
"qualified_name": "p0",
"declaration": "tests/vars/function_param.cc:1:14",
"initializations": ["tests/vars/function_param.cc:1:14"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}, {
"id": 1,
"short_name": "p1",
"qualified_name": "p1",
"declaration": "tests/vars/function_param.cc:1:22",
"initializations": ["tests/vars/function_param.cc:1:22"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}]
}
*/

View File

@ -1,8 +1,50 @@
void foo() {
int a;
{
int a;
}
}
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"functions": [], "id": 0,
"variables": [] "short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [{
"id": 0,
"short_name": "foo",
"qualified_name": "foo",
"declaration": null,
"definition": "tests/vars/function_shadow_local.cc:1:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": [],
"callees": [],
"uses": []
}],
"variables": [{
"id": 0,
"short_name": "a",
"qualified_name": "a",
"declaration": "tests/vars/function_shadow_local.cc:2:7",
"initializations": ["tests/vars/function_shadow_local.cc:2:7"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}, {
"id": 1,
"short_name": "a",
"qualified_name": "a",
"declaration": "tests/vars/function_shadow_local.cc:4:9",
"initializations": ["tests/vars/function_shadow_local.cc:4:9"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}]
} }
*/ */

View File

@ -1,8 +1,47 @@
void foo(int p) {
int p = 0;
}
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"functions": [], "id": 0,
"variables": [] "short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [{
"id": 0,
"short_name": "foo",
"qualified_name": "foo",
"declaration": null,
"definition": "tests/vars/function_shadow_param.cc:1:6",
"declaring_type": null,
"base": null,
"derived": [],
"locals": [],
"callers": [],
"callees": [],
"uses": []
}],
"variables": [{
"id": 0,
"short_name": "p",
"qualified_name": "p",
"declaration": "tests/vars/function_shadow_param.cc:1:14",
"initializations": ["tests/vars/function_shadow_param.cc:1:14"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}, {
"id": 1,
"short_name": "p",
"qualified_name": "p",
"declaration": "tests/vars/function_shadow_param.cc:2:7",
"initializations": ["tests/vars/function_shadow_param.cc:2:7"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}]
} }
*/ */

View File

@ -1,8 +1,23 @@
static int global = 0;
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [{
"functions": [], "id": 0,
"variables": [] "short_name": "",
"qualified_name": "",
"declaration": null
}],
"functions": [],
"variables": [{
"id": 0,
"short_name": "global",
"qualified_name": "global",
"declaration": "tests/vars/global_variable.cc:1:12",
"initializations": ["tests/vars/global_variable.cc:1:12"],
"variable_type": 0,
"declaring_type": null,
"uses": []
}]
} }
*/ */

View File

@ -1,8 +1,18 @@
extern int global;
/* /*
OUTPUT: OUTPUT:
{ {
"types": [], "types": [],
"functions": [], "functions": [],
"variables": [] "variables": [{
"id": 0,
"short_name": "global",
"qualified_name": "global",
"declaration": "tests/vars/global_variable_decl_only.cc:1:12",
"initializations": [],
"variable_type": null,
"declaring_type": null,
"uses": []
}]
} }
*/ */