aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/TypeSystem
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/TypeSystem')
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp282
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h15
2 files changed, 217 insertions, 80 deletions
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index c15b15e736fb..7150fdc78476 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -75,7 +75,7 @@
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
-#include <stdio.h>
+#include <cstdio>
#include <mutex>
@@ -163,7 +163,6 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
if (auto *baseDtorDecl = base_record->getDestructor()) {
if (baseDtorDecl->isVirtual()) {
- path.Decls = baseDtorDecl;
decls.push_back(baseDtorDecl);
return true;
} else
@@ -171,12 +170,11 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
}
// Otherwise, search for name in the base class.
- for (path.Decls = base_record->lookup(name); !path.Decls.empty();
- path.Decls = path.Decls.slice(1)) {
+ for (path.Decls = base_record->lookup(name).begin();
+ path.Decls != path.Decls.end(); ++path.Decls) {
if (auto *method_decl =
- llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
+ llvm::dyn_cast<clang::CXXMethodDecl>(*path.Decls))
if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
- path.Decls = method_decl;
decls.push_back(method_decl);
return true;
}
@@ -479,6 +477,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
case clang::Language::OpenCL:
LangStd = LangStandard::lang_opencl10;
break;
+ case clang::Language::OpenCLCXX:
+ LangStd = LangStandard::lang_openclcpp;
+ break;
case clang::Language::CUDA:
LangStd = LangStandard::lang_cuda;
break;
@@ -686,8 +687,8 @@ void TypeSystemClang::SetTargetTriple(llvm::StringRef target_triple) {
void TypeSystemClang::SetExternalSource(
llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
ASTContext &ast = getASTContext();
- ast.setExternalSource(ast_source_up);
ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
+ ast.setExternalSource(ast_source_up);
}
ASTContext &TypeSystemClang::getASTContext() {
@@ -745,7 +746,7 @@ void TypeSystemClang::CreateASTContext() {
*m_diagnostics_engine_up, *m_file_manager_up);
m_ast_up = std::make_unique<ASTContext>(
*m_language_options_up, *m_source_manager_up, *m_identifier_table_up,
- *m_selector_table_up, *m_builtins_up);
+ *m_selector_table_up, *m_builtins_up, TU_Complete);
m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>();
m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false);
@@ -1356,9 +1357,11 @@ CompilerType TypeSystemClang::CreateRecordType(
}
namespace {
- bool IsValueParam(const clang::TemplateArgument &argument) {
- return argument.getKind() == TemplateArgument::Integral;
- }
+/// Returns true iff the given TemplateArgument should be represented as an
+/// NonTypeTemplateParmDecl in the AST.
+bool IsValueParam(const clang::TemplateArgument &argument) {
+ return argument.getKind() == TemplateArgument::Integral;
+}
}
static TemplateParameterList *CreateTemplateParameterList(
@@ -1462,6 +1465,99 @@ void TypeSystemClang::CreateFunctionTemplateSpecializationInfo(
template_args_ptr, nullptr);
}
+/// Returns true if the given template parameter can represent the given value.
+/// For example, `typename T` can represent `int` but not integral values such
+/// as `int I = 3`.
+static bool TemplateParameterAllowsValue(NamedDecl *param,
+ const TemplateArgument &value) {
+ if (auto *type_param = llvm::dyn_cast<TemplateTypeParmDecl>(param)) {
+ // Compare the argument kind, i.e. ensure that <typename> != <int>.
+ if (value.getKind() != TemplateArgument::Type)
+ return false;
+ } else if (auto *type_param =
+ llvm::dyn_cast<NonTypeTemplateParmDecl>(param)) {
+ // Compare the argument kind, i.e. ensure that <typename> != <int>.
+ if (!IsValueParam(value))
+ return false;
+ // Compare the integral type, i.e. ensure that <int> != <char>.
+ if (type_param->getType() != value.getIntegralType())
+ return false;
+ } else {
+ // There is no way to create other parameter decls at the moment, so we
+ // can't reach this case during normal LLDB usage. Log that this happened
+ // and assert.
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ LLDB_LOG(log,
+ "Don't know how to compare template parameter to passed"
+ " value. Decl kind of parameter is: {0}",
+ param->getDeclKindName());
+ lldbassert(false && "Can't compare this TemplateParmDecl subclass");
+ // In release builds just fall back to marking the parameter as not
+ // accepting the value so that we don't try to fit an instantiation to a
+ // template that doesn't fit. E.g., avoid that `S<1>` is being connected to
+ // `template<typename T> struct S;`.
+ return false;
+ }
+ return true;
+}
+
+/// Returns true if the given class template declaration could produce an
+/// instantiation with the specified values.
+/// For example, `<typename T>` allows the arguments `float`, but not for
+/// example `bool, float` or `3` (as an integer parameter value).
+static bool ClassTemplateAllowsToInstantiationArgs(
+ ClassTemplateDecl *class_template_decl,
+ const TypeSystemClang::TemplateParameterInfos &instantiation_values) {
+
+ TemplateParameterList &params = *class_template_decl->getTemplateParameters();
+
+ // Save some work by iterating only once over the found parameters and
+ // calculate the information related to parameter packs.
+
+ // Contains the first pack parameter (or non if there are none).
+ llvm::Optional<NamedDecl *> pack_parameter;
+ // Contains the number of non-pack parameters.
+ size_t non_pack_params = params.size();
+ for (size_t i = 0; i < params.size(); ++i) {
+ NamedDecl *param = params.getParam(i);
+ if (param->isParameterPack()) {
+ pack_parameter = param;
+ non_pack_params = i;
+ break;
+ }
+ }
+
+ // The found template needs to have compatible non-pack template arguments.
+ // E.g., ensure that <typename, typename> != <typename>.
+ // The pack parameters are compared later.
+ if (non_pack_params != instantiation_values.args.size())
+ return false;
+
+ // Ensure that <typename...> != <typename>.
+ if (pack_parameter.hasValue() != instantiation_values.hasParameterPack())
+ return false;
+
+ // Compare the first pack parameter that was found with the first pack
+ // parameter value. The special case of having an empty parameter pack value
+ // always fits to a pack parameter.
+ // E.g., ensure that <int...> != <typename...>.
+ if (pack_parameter && !instantiation_values.packed_args->args.empty() &&
+ !TemplateParameterAllowsValue(
+ *pack_parameter, instantiation_values.packed_args->args.front()))
+ return false;
+
+ // Compare all the non-pack parameters now.
+ // E.g., ensure that <int> != <long>.
+ for (const auto pair : llvm::zip_first(instantiation_values.args, params)) {
+ const TemplateArgument &passed_arg = std::get<0>(pair);
+ NamedDecl *found_param = std::get<1>(pair);
+ if (!TemplateParameterAllowsValue(found_param, passed_arg))
+ return false;
+ }
+
+ return class_template_decl;
+}
+
ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
DeclContext *decl_ctx, OptionalClangModuleID owning_module,
lldb::AccessType access_type, const char *class_name, int kind,
@@ -1475,12 +1571,22 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
IdentifierInfo &identifier_info = ast.Idents.get(class_name);
DeclarationName decl_name(&identifier_info);
+ // Search the AST for an existing ClassTemplateDecl that could be reused.
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
-
for (NamedDecl *decl : result) {
class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
- if (class_template_decl)
- return class_template_decl;
+ if (!class_template_decl)
+ continue;
+ // The class template has to be able to represents the instantiation
+ // values we received. Without this we might end up putting an instantiation
+ // with arguments such as <int, int> to a template such as:
+ // template<typename T> struct S;
+ // Connecting the instantiation to an incompatible template could cause
+ // problems later on.
+ if (!ClassTemplateAllowsToInstantiationArgs(class_template_decl,
+ template_param_infos))
+ continue;
+ return class_template_decl;
}
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
@@ -1866,8 +1972,8 @@ TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
SetOwningModule(using_decl, owning_module);
clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
- getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
- target);
+ getASTContext(), current_decl_ctx, clang::SourceLocation(),
+ target->getDeclName(), using_decl, target);
SetOwningModule(shadow_decl, owning_module);
using_decl->addShadowDecl(shadow_decl);
current_decl_ctx->addDecl(using_decl);
@@ -2114,11 +2220,10 @@ ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
return decl;
}
-void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl,
- ParmVarDecl **params,
- unsigned num_params) {
+void TypeSystemClang::SetFunctionParameters(
+ FunctionDecl *function_decl, llvm::ArrayRef<ParmVarDecl *> params) {
if (function_decl)
- function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
+ function_decl->setParams(params);
}
CompilerType
@@ -2470,42 +2575,6 @@ ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) {
return nullptr;
}
-bool TypeSystemClang::SetTagTypeKind(clang::QualType tag_qual_type,
- int kind) const {
- const clang::Type *clang_type = tag_qual_type.getTypePtr();
- if (clang_type) {
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
- if (tag_type) {
- clang::TagDecl *tag_decl =
- llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
- if (tag_decl) {
- tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
- return true;
- }
- }
- }
- return false;
-}
-
-bool TypeSystemClang::SetDefaultAccessForRecordFields(
- clang::RecordDecl *record_decl, int default_accessibility,
- int *assigned_accessibilities, size_t num_assigned_accessibilities) {
- if (record_decl) {
- uint32_t field_idx;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(),
- field_end = record_decl->field_end(), field_idx = 0;
- field != field_end; ++field, ++field_idx) {
- // If no accessibility was assigned, assign the correct one
- if (field_idx < num_assigned_accessibilities &&
- assigned_accessibilities[field_idx] == clang::AS_none)
- field->setAccess((clang::AccessSpecifier)default_accessibility);
- }
- return true;
- }
- return false;
-}
-
clang::DeclContext *
TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
return GetDeclContextForType(ClangUtil::GetQualType(type));
@@ -4697,7 +4766,6 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Void:
break;
- case clang::BuiltinType::Bool:
case clang::BuiltinType::Char_S:
case clang::BuiltinType::SChar:
case clang::BuiltinType::WChar_S:
@@ -4708,6 +4776,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Int128:
return lldb::eEncodingSint;
+ case clang::BuiltinType::Bool:
case clang::BuiltinType::Char_U:
case clang::BuiltinType::UChar:
case clang::BuiltinType::WChar_U:
@@ -4889,6 +4958,75 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::SveFloat64x4:
break;
+ // RISC-V V builtin types.
+ case clang::BuiltinType::RvvInt8mf8:
+ case clang::BuiltinType::RvvInt8mf4:
+ case clang::BuiltinType::RvvInt8mf2:
+ case clang::BuiltinType::RvvInt8m1:
+ case clang::BuiltinType::RvvInt8m2:
+ case clang::BuiltinType::RvvInt8m4:
+ case clang::BuiltinType::RvvInt8m8:
+ case clang::BuiltinType::RvvUint8mf8:
+ case clang::BuiltinType::RvvUint8mf4:
+ case clang::BuiltinType::RvvUint8mf2:
+ case clang::BuiltinType::RvvUint8m1:
+ case clang::BuiltinType::RvvUint8m2:
+ case clang::BuiltinType::RvvUint8m4:
+ case clang::BuiltinType::RvvUint8m8:
+ case clang::BuiltinType::RvvInt16mf4:
+ case clang::BuiltinType::RvvInt16mf2:
+ case clang::BuiltinType::RvvInt16m1:
+ case clang::BuiltinType::RvvInt16m2:
+ case clang::BuiltinType::RvvInt16m4:
+ case clang::BuiltinType::RvvInt16m8:
+ case clang::BuiltinType::RvvUint16mf4:
+ case clang::BuiltinType::RvvUint16mf2:
+ case clang::BuiltinType::RvvUint16m1:
+ case clang::BuiltinType::RvvUint16m2:
+ case clang::BuiltinType::RvvUint16m4:
+ case clang::BuiltinType::RvvUint16m8:
+ case clang::BuiltinType::RvvInt32mf2:
+ case clang::BuiltinType::RvvInt32m1:
+ case clang::BuiltinType::RvvInt32m2:
+ case clang::BuiltinType::RvvInt32m4:
+ case clang::BuiltinType::RvvInt32m8:
+ case clang::BuiltinType::RvvUint32mf2:
+ case clang::BuiltinType::RvvUint32m1:
+ case clang::BuiltinType::RvvUint32m2:
+ case clang::BuiltinType::RvvUint32m4:
+ case clang::BuiltinType::RvvUint32m8:
+ case clang::BuiltinType::RvvInt64m1:
+ case clang::BuiltinType::RvvInt64m2:
+ case clang::BuiltinType::RvvInt64m4:
+ case clang::BuiltinType::RvvInt64m8:
+ case clang::BuiltinType::RvvUint64m1:
+ case clang::BuiltinType::RvvUint64m2:
+ case clang::BuiltinType::RvvUint64m4:
+ case clang::BuiltinType::RvvUint64m8:
+ case clang::BuiltinType::RvvFloat16mf4:
+ case clang::BuiltinType::RvvFloat16mf2:
+ case clang::BuiltinType::RvvFloat16m1:
+ case clang::BuiltinType::RvvFloat16m2:
+ case clang::BuiltinType::RvvFloat16m4:
+ case clang::BuiltinType::RvvFloat16m8:
+ case clang::BuiltinType::RvvFloat32mf2:
+ case clang::BuiltinType::RvvFloat32m1:
+ case clang::BuiltinType::RvvFloat32m2:
+ case clang::BuiltinType::RvvFloat32m4:
+ case clang::BuiltinType::RvvFloat32m8:
+ case clang::BuiltinType::RvvFloat64m1:
+ case clang::BuiltinType::RvvFloat64m2:
+ case clang::BuiltinType::RvvFloat64m4:
+ case clang::BuiltinType::RvvFloat64m8:
+ case clang::BuiltinType::RvvBool1:
+ case clang::BuiltinType::RvvBool2:
+ case clang::BuiltinType::RvvBool4:
+ case clang::BuiltinType::RvvBool8:
+ case clang::BuiltinType::RvvBool16:
+ case clang::BuiltinType::RvvBool32:
+ case clang::BuiltinType::RvvBool64:
+ break;
+
case clang::BuiltinType::IncompleteMatrixIdx:
break;
}
@@ -6365,7 +6503,7 @@ CompilerType TypeSystemClang::GetChildCompilerTypeAtIndex(
case clang::Type::RValueReference:
if (idx_is_valid) {
const clang::ReferenceType *reference_type =
- llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
+ llvm::cast<clang::ReferenceType>(GetQualType(type).getTypePtr());
CompilerType pointee_clang_type =
GetType(reference_type->getPointeeType());
if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
@@ -6536,10 +6674,11 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
if (cxx_record_decl->lookupInBases(
[decl_name](const clang::CXXBaseSpecifier *specifier,
clang::CXXBasePath &path) {
- path.Decls =
- specifier->getType()->getAsCXXRecordDecl()->lookup(
- decl_name);
- return !path.Decls.empty();
+ CXXRecordDecl *record =
+ specifier->getType()->getAsCXXRecordDecl();
+ auto r = record->lookup(decl_name);
+ path.Decls = r.begin();
+ return !r.empty();
},
paths)) {
clang::CXXBasePaths::const_paths_iterator path,
@@ -6562,9 +6701,10 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
->getDecl());
}
}
- for (clang::NamedDecl *path_decl : path->Decls) {
+ for (clang::DeclContext::lookup_iterator I = path->Decls, E;
+ I != E; ++I) {
child_idx = GetIndexForRecordChild(
- parent_record_decl, path_decl, omit_empty_base_classes);
+ parent_record_decl, *I, omit_empty_base_classes);
if (child_idx == UINT32_MAX) {
child_indexes.clear();
return 0;
@@ -9234,11 +9374,11 @@ CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName(
void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
std::vector<CompilerDecl> found_decls;
- if (opaque_decl_ctx) {
+ SymbolFile *symbol_file = GetSymbolFile();
+ if (opaque_decl_ctx && symbol_file) {
DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
std::set<DeclContext *> searched;
std::multimap<DeclContext *, DeclContext *> search_queue;
- SymbolFile *symbol_file = GetSymbolFile();
for (clang::DeclContext *decl_context = root_decl_ctx;
decl_context != nullptr && found_decls.empty();
@@ -9332,10 +9472,10 @@ uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
clang::DeclContext *child_decl_ctx,
ConstString *child_name,
CompilerType *child_type) {
- if (frame_decl_ctx) {
+ SymbolFile *symbol_file = GetSymbolFile();
+ if (frame_decl_ctx && symbol_file) {
std::set<DeclContext *> searched;
std::multimap<DeclContext *, DeclContext *> search_queue;
- SymbolFile *symbol_file = GetSymbolFile();
// Get the lookup scope for the decl we're trying to find.
clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
@@ -9581,7 +9721,8 @@ ScratchTypeSystemClang::ScratchTypeSystemClang(Target &target,
llvm::Triple triple)
: TypeSystemClang("scratch ASTContext", triple), m_triple(triple),
m_target_wp(target.shared_from_this()),
- m_persistent_variables(new ClangPersistentVariables) {
+ m_persistent_variables(
+ new ClangPersistentVariables(target.shared_from_this())) {
m_scratch_ast_source_up = CreateASTSource();
m_scratch_ast_source_up->InstallASTContext(*this);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
@@ -9649,7 +9790,8 @@ ScratchTypeSystemClang::CreateUtilityFunction(std::string text,
return {};
return std::make_unique<ClangUtilityFunction>(
- *target_sp.get(), std::move(text), std::move(name));
+ *target_sp.get(), std::move(text), std::move(name),
+ target_sp->GetDebugUtilityExpression());
}
PersistentExpressionState *
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index f37652ff477a..701e4ca42e39 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -9,7 +9,7 @@
#ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
#define LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
-#include <stdint.h>
+#include <cstdint>
#include <functional>
#include <initializer_list>
@@ -265,7 +265,7 @@ public:
clang::DeclContext::lookup_result result = decl_context->lookup(myName);
if (!result.empty()) {
- clang::NamedDecl *named_decl = result[0];
+ clang::NamedDecl *named_decl = *result.begin();
if (const RecordDeclType *record_decl =
llvm::dyn_cast<RecordDeclType>(named_decl))
compiler_type.SetCompilerType(
@@ -328,6 +328,8 @@ public:
(!packed_args || !packed_args->packed_args);
}
+ bool hasParameterPack() const { return static_cast<bool>(packed_args); }
+
llvm::SmallVector<const char *, 2> names;
llvm::SmallVector<clang::TemplateArgument, 2> args;
@@ -378,13 +380,6 @@ public:
bool isForwardDecl, bool isInternal,
ClangASTMetadata *metadata = nullptr);
- bool SetTagTypeKind(clang::QualType type, int kind) const;
-
- bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl,
- int default_accessibility,
- int *assigned_accessibilities,
- size_t num_assigned_accessibilities);
-
// Returns a mask containing bits from the TypeSystemClang::eTypeXXX
// enumerations
@@ -421,7 +416,7 @@ public:
int storage, bool add_decl = false);
void SetFunctionParameters(clang::FunctionDecl *function_decl,
- clang::ParmVarDecl **params, unsigned num_params);
+ llvm::ArrayRef<clang::ParmVarDecl *> params);
CompilerType CreateBlockPointerType(const CompilerType &function_type);