blob: 8bf36439ce7ea58117810e2cbed20609e1eda502 [file] [log] [blame]
// Copyright 2020 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/expr/resolve_type.h"
#include "src/developer/debug/zxdb/expr/find_name.h"
#include "src/developer/debug/zxdb/expr/found_name.h"
#include "src/developer/debug/zxdb/symbols/type.h"
namespace zxdb {
fxl::RefPtr<Type> GetConcreteType(const FindNameContext& find_name_context, const Type* type) {
if (!type)
return fxl::RefPtr<Type>();
// Iteratively strip C-V qualifications, follow typedefs, and follow forward
// declarations.
fxl::RefPtr<Type> cur = RefPtrTo(type);
do {
// Follow forward declarations.
if (cur->is_declaration()) {
cur = FindTypeDefinition(find_name_context, cur.get());
if (cur->is_declaration())
break; // Declaration can't be resolved, give up.
}
// Strip C-V qualifiers and follow typedefs.
cur = RefPtrTo(cur->StripCVT());
} while (cur && cur->is_declaration());
return cur;
}
fxl::RefPtr<Type> FindTypeDefinition(const FindNameContext& context, const Type* type) {
Identifier ident = type->GetIdentifier();
if (ident.empty()) {
// Some things like modified types don't have real identifier names.
return RefPtrTo(type);
}
fxl::RefPtr<Type> result = FindTypeDefinition(context, ToParsedIdentifier(ident));
if (result)
return result;
return RefPtrTo(type); // Return the same input on failure.
}
fxl::RefPtr<Type> FindTypeDefinition(const FindNameContext& context, ParsedIdentifier looking_for) {
// Search for the first match of a type definition. Note that "find_types" is not desirable here
// since we only want to resolve real definitions. Normally the index contains only definitions
// but if a module contains only declarations that module's index will list the symbol as a
// declaration which we don't want.
FindNameOptions opts(FindNameOptions::kNoKinds);
opts.find_type_defs = true;
opts.max_results = 1;
// The type names will always be fully qualified. Mark the identifier as such and only search the
// global context by clearing the code location.
looking_for.set_qualification(IdentifierQualification::kGlobal);
// The input type name should be fully qualified so explicitly clear out any current code block to
// bypass relative searching. This should be a no-op since the name is globally qualified, but
// saves a little work later.
auto use_context = context;
use_context.block = nullptr;
if (FoundName result = FindName(use_context, opts, looking_for)) {
FX_DCHECK(result.type());
return result.type();
}
return nullptr;
}
} // namespace zxdb