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 {
return get_spelling() + " " + clang::ToString(get_kind());
return clang::ToString(get_kind()) + " " + get_spelling();
}
} // namespace clang

121
main.cpp
View File

@ -52,6 +52,8 @@ template<typename T>
struct Ref {
LocalId<T> id;
clang::SourceLocation loc;
Ref(LocalId<T> id, clang::SourceLocation loc) : id(id), loc(loc) {}
};
using TypeRef = Ref<TypeDef>;
using FuncRef = Ref<FuncDef>;
@ -398,11 +400,6 @@ std::string ParsingDatabase::ToString(bool for_test) {
writer.String("declaration");
WriteLocation(writer, def.declaration);
if (def.initializations.size() == 0) {
writer.EndObject();
continue;
}
writer.String("initializations");
WriteLocationArray(writer, def.initializations);
@ -491,7 +488,8 @@ struct NamespaceStack {
void Push(const std::string& ns);
void Pop();
std::string ComputeQualifiedPrefix();
std::string ComputeQualifiedName(
ParsingDatabase* db, std::optional<TypeId> declaring_type, std::string short_name);
static NamespaceStack kEmpty;
};
@ -505,10 +503,17 @@ void NamespaceStack::Pop() {
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;
for (const std::string& ns : stack)
result += ns + "::";
result += short_name;
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) {
// 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();
switch (parent.get_kind()) {
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) {
for (int i = 0; i < *level; ++i)
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;
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) {
Dump(var);
//Dump(var);
VarId var_id = db->ToVarId(var.get_usr());
@ -587,7 +591,8 @@ void HandleVarDecl(ParsingDatabase* db, NamespaceStack* ns, clang::Cursor var, s
// instance alive.
VarDef* var_def = db->Resolve(var_id);
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) {
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();
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->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 {
ParsingDatabase* db;
NamespaceStack* ns;
FuncDefinitionParam(ParsingDatabase* db, NamespaceStack* ns)
: db(db), ns(ns) {}
FuncId func_id;
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) {
//std::cout << "VistFunc got " << cursor.ToString() << std::endl;
switch (cursor.get_kind()) {
// TODO: Maybe we should default to recurse?
/*
case CXCursor_CompoundStmt:
case CXCursor_DeclStmt:
case CXCursor_CallExpr:
case CXCursor_UnexposedExpr:
case CXCursor_UnaryExpr:
return clang::VisiterResult::Recurse;
*/
case CXCursor_DeclRefExpr:
InsertReference(param->db, param->func_id, cursor);
break;
case CXCursor_VarDecl:
case CXCursor_ParmDecl:
HandleVarDecl(param->db, param->ns, cursor, std::nullopt);
return clang::VisiterResult::Continue;
return clang::VisiterResult::Recurse;
case CXCursor_ReturnStmt:
return clang::VisiterResult::Continue;
return clang::VisiterResult::Recurse;
default:
std::cerr << "Unhandled VisitFuncDefinition kind " << clang::ToString(cursor.get_kind()) << std::endl;
return clang::VisiterResult::Continue;
//std::cerr << "Unhandled VisitFuncDefinition kind " << clang::ToString(cursor.get_kind()) << std::endl;
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);
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 =
ns->ComputeQualifiedPrefix() + type_name + func_def->short_name;
ns->ComputeQualifiedName(db, declaring_type, func_def->short_name);
if (declaring_type && !func_def->declaration) {
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_2 = clang_getCursorResultType(func.cx_cursor);
Dump(func);
FuncDefinitionParam funcDefinitionParam(db, &NamespaceStack::kEmpty);
//Dump(func);
FuncDefinitionParam funcDefinitionParam(db, &NamespaceStack::kEmpty, func_id);
func.VisitChildren(&VisitFuncDefinition, &funcDefinitionParam);
//CXType return_type = clang_getResultType(func.get_type());
@ -735,6 +777,7 @@ clang::VisiterResult VisitClassDecl(clang::Cursor cursor, clang::Cursor parent,
break;
case CXCursor_FieldDecl:
case CXCursor_VarDecl:
HandleVarDecl(param->db, param->ns, cursor, param->active_type);
break;
@ -747,21 +790,23 @@ clang::VisiterResult VisitClassDecl(clang::Cursor cursor, clang::Cursor parent,
}
void HandleClassDecl(clang::Cursor cursor, ParsingDatabase* db, NamespaceStack* ns) {
TypeId id = db->ToTypeId(cursor.get_usr());
TypeDef* def = db->Resolve(id);
TypeId func_id = db->ToTypeId(cursor.get_usr());
TypeDef* func_def = db->Resolve(func_id);
def->short_name = cursor.get_spelling();
def->qualified_name = ns->ComputeQualifiedPrefix() + cursor.get_spelling();
func_def->short_name = 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 (!def->declaration)
def->declaration = cursor.get_source_location();
if (!func_def->declaration)
func_def->declaration = cursor.get_source_location();
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);
}
@ -797,6 +842,10 @@ clang::VisiterResult VisitFile(clang::Cursor cursor, clang::Cursor parent, FileP
HandleFunc(param->db, param->ns, cursor, std::nullopt);
break;
case CXCursor_VarDecl:
HandleVarDecl(param->db, param->ns, cursor, std::nullopt);
break;
default:
std::cerr << "Unhandled VisitFile kind " << clang::ToString(cursor.get_kind()) << std::endl;
break;
@ -821,9 +870,9 @@ ParsingDatabase Parse(std::string filename) {
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
clang::TranslationUnit tu(index, filename, args);
//std::cout << "Start document dump" << std::endl;
//Dump(tu.document_cursor());
//std::cout << "Done document dump" << std::endl << std::endl;
std::cout << "Start document dump" << std::endl;
Dump(tu.document_cursor());
std::cout << "Done document dump" << std::endl << std::endl;
ParsingDatabase db;
NamespaceStack ns;
@ -856,7 +905,7 @@ void Write(const std::vector<std::string>& strs) {
int main(int argc, char** argv) {
for (std::string path : GetFilesInFolder("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.
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,
"short_name": "foo",
"qualified_name": "hello::foo",
"declaration": "tests/function_declaration_in_namespace.cc:2:6"
"declaration": "tests/namespaces/function_declaration.cc:2:6"
}],
"variables": []
}

View File

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

View File

@ -12,7 +12,7 @@ OUTPUT:
"short_name": "Foo",
"qualified_name": "hello::Foo",
"declaration": null,
"definition": "tests/method_declaration_in_namespace.cc:2:7",
"definition": "tests/namespaces/method_declaration.cc:2:7",
"parents": [],
"derived": [],
"types": [],
@ -24,7 +24,7 @@ OUTPUT:
"id": 0,
"short_name": "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
}],
"variables": []

View File

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

View File

@ -12,7 +12,7 @@ OUTPUT:
"short_name": "Foo",
"qualified_name": "hello::Foo",
"declaration": null,
"definition": "tests/method_inline_declaration_in_namespace.cc:2:7",
"definition": "tests/namespaces/method_inline_declaration.cc:2:7",
"parents": [],
"derived": [],
"types": [],
@ -25,7 +25,7 @@ OUTPUT:
"short_name": "foo",
"qualified_name": "hello::Foo::foo",
"declaration": null,
"definition": "tests/method_inline_declaration_in_namespace.cc:3:8",
"definition": "tests/namespaces/method_inline_declaration.cc:3:8",
"declaring_type": 0,
"base": null,
"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:
{
"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": [],
"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:
{
"types": [],
"functions": [],
"variables": []
"types": [{
"id": 0,
"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:
{
"types": [],
"functions": [],
"variables": []
"types": [{
"id": 0,
"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:
{
"types": [],
"functions": [],
"variables": []
"types": [{
"id": 0,
"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:
{
"types": [],
"functions": [],
"variables": []
"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

@ -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:
{
"types": [],
"functions": [],
"variables": []
"types": [{
"id": 0,
"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:
{
"types": [],
"functions": [],
"variables": []
"types": [{
"id": 0,
"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:
{
"types": [],
"functions": [],
"variables": []
"types": [{
"id": 0,
"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:
{
"types": [],
"functions": [],
"variables": []
"types": [],
"functions": [],
"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": []
}]
}
*/