blob: bcac756b499bc7b3d987bd7b6e02cdfcb27c3745 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/symbols/symbol_utils.h"
#include <gtest/gtest.h>
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/collection.h"
#include "src/developer/debug/zxdb/symbols/data_member.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/namespace.h"
#include "src/developer/debug/zxdb/symbols/symbol_test_parent_setter.h"
#include "src/developer/debug/zxdb/symbols/type_test_support.h"
#include "src/developer/debug/zxdb/symbols/variable.h"
namespace zxdb {
// This tests GetSymbolScopePrefix and checks Symbol::GetFullName() for those types.
TEST(SymbolUtils, GetSymbolScopePrefix) {
fxl::RefPtr<Namespace> ns1 = fxl::MakeRefCounted<Namespace>();
ns1->set_assigned_name("ns1");
EXPECT_EQ("::", GetSymbolScopePrefix(ns1.get()).GetFullName());
EXPECT_EQ("ns1", ns1->GetFullName());
// Nested anonymous namespace.
fxl::RefPtr<Namespace> ns2 = fxl::MakeRefCounted<Namespace>();
SymbolTestParentSetter ns2_parent(ns2, ns1);
EXPECT_EQ("::ns1", GetSymbolScopePrefix(ns2.get()).GetFullName());
EXPECT_EQ("ns1::$anon", ns2->GetFullName());
// Struct inside anonymous namespace.
fxl::RefPtr<Collection> st = fxl::MakeRefCounted<Collection>(DwarfTag::kStructureType);
SymbolTestParentSetter st_parent(st, ns2);
st->set_assigned_name("Struct");
EXPECT_EQ("::ns1::$anon", GetSymbolScopePrefix(st.get()).GetFullName());
EXPECT_EQ("ns1::$anon::Struct", st->GetFullName());
// Data member inside structure.
fxl::RefPtr<DataMember> dm = fxl::MakeRefCounted<DataMember>();
SymbolTestParentSetter dm_parent(dm, st);
dm->set_assigned_name("data_");
EXPECT_EQ("::ns1::$anon::Struct", GetSymbolScopePrefix(dm.get()).GetFullName());
EXPECT_EQ("ns1::$anon::Struct::data_", dm->GetFullName());
}
// Tests some symbol scope descriptions with respect to functions.
TEST(SymbolUtils, SymbolScopeFunctions) {
// Outer namespace.
fxl::RefPtr<Namespace> ns = fxl::MakeRefCounted<Namespace>();
ns->set_assigned_name("ns");
// Function definition inside namespace.
fxl::RefPtr<Function> fn = fxl::MakeRefCounted<Function>(DwarfTag::kSubprogram);
SymbolTestParentSetter fn_parent(fn, ns);
fn->set_assigned_name("Function");
EXPECT_EQ("::ns", GetSymbolScopePrefix(fn.get()).GetFullName());
EXPECT_EQ("ns::Function", fn->GetFullName());
// Lexical scope inside the function. This should not appear in names.
// TODO(brettw) these nested function scopes should include paramter names.
fxl::RefPtr<CodeBlock> block = fxl::MakeRefCounted<CodeBlock>(DwarfTag::kLexicalBlock);
SymbolTestParentSetter block_parent(block, fn);
EXPECT_EQ("::ns::Function", GetSymbolScopePrefix(block.get()).GetFullName());
EXPECT_EQ("", block->GetFullName());
// Type defined inside the function is qualified by the function name. This format matches GDB and
// LLDB.
fxl::RefPtr<Collection> sc = fxl::MakeRefCounted<Collection>(DwarfTag::kStructureType);
SymbolTestParentSetter sc_parent(sc, block);
sc->set_assigned_name("Struct");
EXPECT_EQ("::ns::Function", GetSymbolScopePrefix(sc.get()).GetFullName());
EXPECT_EQ("ns::Function::Struct", sc->GetFullName());
// Variable defined inside the function. Currently these are qualified with the function name like
// the types above. But this may need to change depending on how these are surfaced to the user.
// Qualifying local variables seems weird and we likely don't want this, but it currently works
// that way because it falls out of the algorithm. However, the local variable printer may well
// not need this code path.
fxl::RefPtr<Variable> var = fxl::MakeRefCounted<Variable>(DwarfTag::kVariable);
SymbolTestParentSetter var_parent(var, block);
var->set_assigned_name("var");
EXPECT_EQ("::ns::Function", GetSymbolScopePrefix(var.get()).GetFullName());
EXPECT_EQ("ns::Function::var", var->GetFullName());
}
TEST(SymbolUtils, AddCVQualifiersToMatch) {
auto int32_type = MakeInt32Type();
auto int64_type = MakeInt64Type();
// Null reference keeps the same thing.
auto result = AddCVQualifiersToMatch(nullptr, int32_type);
EXPECT_EQ(result.get(), int32_type.get());
// Non-C-V reference type does nothing.
result = AddCVQualifiersToMatch(int64_type.get(), int32_type);
EXPECT_EQ(result.get(), int32_type.get());
EXPECT_EQ("int32_t", result->GetFullName());
// Copy a const qualifier.
auto const_int64_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kConstType, int64_type);
result = AddCVQualifiersToMatch(const_int64_type.get(), int32_type);
EXPECT_EQ("const int32_t", result->GetFullName());
// Copy a volatile + const qualifier.
auto volatile_const_int64_type =
fxl::MakeRefCounted<ModifiedType>(DwarfTag::kVolatileType, const_int64_type);
result = AddCVQualifiersToMatch(volatile_const_int64_type.get(), int32_type);
EXPECT_EQ("volatile int32_t const", result->GetFullName());
}
} // namespace zxdb