Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lldb/docs/dil-expr-lang.ebnf
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ expression = unary_expression ;
unary_expression = postfix_expression
| unary_operator expression ;

unary_operator = "*" | "&" ;
unary_operator = "*" | "&" | "+" | "-";

postfix_expression = primary_expression
| postfix_expression "[" integer_literal "]"
Expand Down
7 changes: 7 additions & 0 deletions lldb/include/lldb/Symbol/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,13 @@ class TypeSystem : public PluginInterface,
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
bool expand_pack);

// DIL

virtual bool IsPromotableIntegerType(lldb::opaque_compiler_type_t type);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a Doxygen comment explaining the semantics of this function?


virtual llvm::Expected<CompilerType>
DoIntegralPromotion(CompilerType from, ExecutionContextScope *exe_scope);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure what to write here, since the semantics is dependent on the type system. I wrote a general idea for C++, but I suspect that for Swift this might do opposite things, like not promoting integers at all and returning an error for Bool.


// Dumping types

#ifndef NDEBUG
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/ValueObject/DILAST.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ enum class NodeKind {
enum class UnaryOpKind {
AddrOf, // "&"
Deref, // "*"
Minus, // "-"
Plus, // "+"
};

/// Forward declaration, for use in DIL AST nodes. Definition is at the very
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/ValueObject/DILEval.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class Interpreter : Visitor {
llvm::Expected<lldb::ValueObjectSP>
Visit(const FloatLiteralNode *node) override;

llvm::Expected<lldb::ValueObjectSP>
UnaryConversion(lldb::ValueObjectSP valobj);
llvm::Expected<CompilerType>
PickIntegerType(lldb::TypeSystemSP type_system,
std::shared_ptr<ExecutionContextScope> ctx,
Expand Down
96 changes: 96 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7320,6 +7320,102 @@ CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
return CompilerType();
}

bool TypeSystemClang::IsPromotableIntegerType(
lldb::opaque_compiler_type_t type) {
// Unscoped enums are always considered as promotable, even if their
// underlying type does not need to be promoted (e.g. "int").
bool is_signed = false;
bool isUnscopedEnumerationType =
IsEnumerationType(type, is_signed) && !IsScopedEnumerationType(type);
if (isUnscopedEnumerationType)
return true;

switch (GetBasicTypeEnumeration(type)) {
case lldb::eBasicTypeBool:
case lldb::eBasicTypeChar:
case lldb::eBasicTypeSignedChar:
case lldb::eBasicTypeUnsignedChar:
case lldb::eBasicTypeShort:
case lldb::eBasicTypeUnsignedShort:
case lldb::eBasicTypeWChar:
case lldb::eBasicTypeSignedWChar:
case lldb::eBasicTypeUnsignedWChar:
case lldb::eBasicTypeChar16:
case lldb::eBasicTypeChar32:
return true;

default:
return false;
}

llvm_unreachable("All cases handled above.");
}

llvm::Expected<CompilerType>
TypeSystemClang::DoIntegralPromotion(CompilerType from,
ExecutionContextScope *exe_scope) {
if (!from.IsInteger() && !from.IsUnscopedEnumerationType())
return from;

if (!from.IsPromotableIntegerType())
return from;

if (from.IsUnscopedEnumerationType()) {
EnumDecl *enum_decl = GetAsEnumDecl(from);
CompilerType promotion_type = GetType(enum_decl->getPromotionType());
return DoIntegralPromotion(promotion_type, exe_scope);
}

lldb::BasicType builtin_type =
from.GetCanonicalType().GetBasicTypeEnumeration();
uint64_t from_size = 0;
if (builtin_type == lldb::eBasicTypeWChar ||
builtin_type == lldb::eBasicTypeSignedWChar ||
builtin_type == lldb::eBasicTypeUnsignedWChar ||
builtin_type == lldb::eBasicTypeChar16 ||
builtin_type == lldb::eBasicTypeChar32) {
// Find the type that can hold the entire range of values for our type.
bool is_signed = from.IsSigned();
llvm::Expected<uint64_t> from_size = from.GetByteSize(exe_scope);
if (!from_size)
return from_size.takeError();
CompilerType promote_types[] = {
GetBasicTypeFromAST(lldb::eBasicTypeInt),
GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt),
GetBasicTypeFromAST(lldb::eBasicTypeLong),
GetBasicTypeFromAST(lldb::eBasicTypeUnsignedLong),
GetBasicTypeFromAST(lldb::eBasicTypeLongLong),
GetBasicTypeFromAST(lldb::eBasicTypeUnsignedLongLong),
};
for (CompilerType &type : promote_types) {
llvm::Expected<uint64_t> byte_size = type.GetByteSize(exe_scope);
if (!byte_size)
return byte_size.takeError();
if (*from_size < *byte_size ||
(*from_size == *byte_size && is_signed == type.IsSigned())) {
return type;
}
}
llvm_unreachable("char type should fit into long long");
}

// Here we can promote only to "int" or "unsigned int".
CompilerType int_type = GetBasicTypeFromAST(lldb::eBasicTypeInt);
llvm::Expected<uint64_t> int_byte_size = int_type.GetByteSize(exe_scope);
if (!int_byte_size)
return int_byte_size.takeError();

// Signed integer types can be safely promoted to "int".
if (from.IsSigned()) {
return int_type;
}
// Unsigned integer types are promoted to "unsigned int" if "int" cannot hold
// their entire value range.
return (from_size == *int_byte_size)
? GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt)
: int_type;
}

clang::EnumDecl *TypeSystemClang::GetAsEnumDecl(const CompilerType &type) {
const clang::EnumType *enutype =
llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,14 @@ class TypeSystemClang : public TypeSystem {

CompilerType GetTypeForFormatters(void *type) override;

// DIL

bool IsPromotableIntegerType(lldb::opaque_compiler_type_t type) override;

llvm::Expected<CompilerType>
DoIntegralPromotion(CompilerType from,
ExecutionContextScope *exe_scope) override;

#define LLDB_INVALID_DECL_LEVEL UINT32_MAX
// LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if child_decl_ctx
// could not be found in decl_ctx.
Expand Down
28 changes: 4 additions & 24 deletions lldb/source/Symbol/CompilerType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,30 +373,10 @@ bool CompilerType::IsScalarOrUnscopedEnumerationType() const {
}

bool CompilerType::IsPromotableIntegerType() const {
// Unscoped enums are always considered as promotable, even if their
// underlying type does not need to be promoted (e.g. "int").
if (IsUnscopedEnumerationType())
return true;

switch (GetBasicTypeEnumeration()) {
case lldb::eBasicTypeBool:
case lldb::eBasicTypeChar:
case lldb::eBasicTypeSignedChar:
case lldb::eBasicTypeUnsignedChar:
case lldb::eBasicTypeShort:
case lldb::eBasicTypeUnsignedShort:
case lldb::eBasicTypeWChar:
case lldb::eBasicTypeSignedWChar:
case lldb::eBasicTypeUnsignedWChar:
case lldb::eBasicTypeChar16:
case lldb::eBasicTypeChar32:
return true;

default:
return false;
}

llvm_unreachable("All cases handled above.");
if (IsValid())
if (auto type_system_sp = GetTypeSystem())
return type_system_sp->IsPromotableIntegerType(m_type);
return false;
}

bool CompilerType::IsPointerToVoid() const {
Expand Down
10 changes: 10 additions & 0 deletions lldb/source/Symbol/TypeSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ CompilerType TypeSystem::GetTypeForFormatters(void *type) {
return CompilerType(weak_from_this(), type);
}

bool TypeSystem::IsPromotableIntegerType(lldb::opaque_compiler_type_t type) {
return false;
}

llvm::Expected<CompilerType>
TypeSystem::DoIntegralPromotion(CompilerType from,
ExecutionContextScope *exe_scope) {
return CompilerType();
}

bool TypeSystem::IsTemplateType(lldb::opaque_compiler_type_t type) {
return false;
}
Expand Down
Loading
Loading