Author: Stella Stamenova Date: 2022-07-14T10:47:01-07:00 New Revision: c3a28e8a99a6672339a38c468f2519ace5659fa2
URL: https://github.com/llvm/llvm-project/commit/c3a28e8a99a6672339a38c468f2519ace5659fa2 DIFF: https://github.com/llvm/llvm-project/commit/c3a28e8a99a6672339a38c468f2519ace5659fa2.diff LOG: Revert "[lldb] Add support for using integral const static data members in the expression evaluator" This reverts commit 486787210df5ce5eabadc90a7de353ae81101feb. This broke the windows lldb bot: https://lab.llvm.org/buildbot/#/builders/83/builds/21186 Added: Modified: lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h lldb/unittests/SymbolFile/DWARF/CMakeLists.txt lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp Removed: lldb/test/API/lang/cpp/const_static_integral_member/Makefile lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py lldb/test/API/lang/cpp/const_static_integral_member/main.cpp lldb/test/API/lang/cpp/const_static_integral_member_int128/Makefile lldb/test/API/lang/cpp/const_static_integral_member_int128/TestConstStaticIntegralMemberInt128.py lldb/test/API/lang/cpp/const_static_integral_member_int128/main.cpp ################################################################################ diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp index 799ae29e2841c..7a1ac78705474 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -197,27 +197,6 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult( return ret; } -/// Returns true if LLDB can take the address of the given lvalue for the sake -/// of capturing the expression result. Returns false if LLDB should instead -/// store the expression result in a result variable. -static bool CanTakeAddressOfLValue(const Expr *lvalue_expr) { - assert(lvalue_expr->getValueKind() == VK_LValue && - "lvalue_expr not a lvalue"); - - QualType qt = lvalue_expr->getType(); - // If the lvalue has const-qualified non-volatile integral or enum type, then - // the underlying value might come from a const static data member as - // described in C++11 [class.static.data]p3. If that's the case, then the - // value might not have an address if the user didn't also define the member - // in a namespace scope. Taking the address would cause that LLDB later fails - // to link the expression, so those lvalues should be stored in a result - // variable. - if (qt->isIntegralOrEnumerationType() && qt.isConstQualified() && - !qt.isVolatileQualified()) - return false; - return true; -} - bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, DeclContext *DC) { Log *log = GetLog(LLDBLog::Expressions); @@ -286,10 +265,6 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, // - During dematerialization, $0 is marked up as a load address with value // equal to the contents of the structure entry. // - // - Note: if we cannot take an address of the resulting Lvalue (e.g. it's - // a static const member without an out-of-class definition), then we - // follow the Rvalue route. - // // For Rvalues // // - In AST result synthesis the expression E is transformed into an @@ -329,7 +304,7 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, clang::VarDecl *result_decl = nullptr; - if (is_lvalue && CanTakeAddressOfLValue(last_expr)) { + if (is_lvalue) { IdentifierInfo *result_ptr_id; if (expr_type->isFunctionType()) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 10dc8d1fb7c39..4b9354371bda3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2390,7 +2390,6 @@ struct MemberAttributes { uint64_t data_bit_offset = UINT64_MAX; AccessType accessibility = eAccessNone; llvm::Optional<uint64_t> byte_size; - llvm::Optional<DWARFFormValue> const_value_form; DWARFFormValue encoding_form; /// Indicates the byte offset of the word from the base address of the /// structure. @@ -2437,9 +2436,6 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; - case DW_AT_const_value: - const_value_form = form_value; - break; case DW_AT_data_bit_offset: data_bit_offset = form_value.Unsigned(); break; @@ -2591,65 +2587,12 @@ void DWARFASTParserClang::ParseObjCProperty( propAttrs.prop_getter_name, propAttrs.prop_attributes, &metadata)); } -llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue( - const CompilerType &int_type, const DWARFFormValue &form_value) const { - clang::QualType qt = ClangUtil::GetQualType(int_type); - assert(qt->isIntegralOrEnumerationType()); - TypeSystemClang &ts = *llvm::cast<TypeSystemClang>(int_type.GetTypeSystem()); - clang::ASTContext &ast = ts.getASTContext(); - - const unsigned type_bits = ast.getIntWidth(qt); - const bool is_unsigned = qt->isUnsignedIntegerType(); - - // The maximum int size supported at the moment by this function. Limited - // by the uint64_t return type of DWARFFormValue::Signed/Unsigned. - constexpr std::size_t max_bit_size = 64; - - // For values bigger than 64 bit (e.g. __int128_t values), - // DWARFFormValue's Signed/Unsigned functions will return wrong results so - // emit an error for now. - if (type_bits > max_bit_size) { - auto msg = llvm::formatv("Can only parse integers with up to {0} bits, but " - "given integer has {1} bits.", - max_bit_size, type_bits); - return llvm::createStringError(llvm::inconvertibleErrorCode(), msg.str()); - } - - // Construct an APInt with the maximum bit size and the given integer. - llvm::APInt result(max_bit_size, form_value.Unsigned(), !is_unsigned); - - // Calculate how many bits are required to represent the input value. - // For unsigned types, take the number of active bits in the APInt. - // For signed types, ask APInt how many bits are required to represent the - // signed integer. - const unsigned required_bits = - is_unsigned ? result.getActiveBits() : result.getMinSignedBits(); - - // If the input value doesn't fit into the integer type, return an error. - if (required_bits > type_bits) { - std::string value_as_str = is_unsigned - ? std::to_string(form_value.Unsigned()) - : std::to_string(form_value.Signed()); - auto msg = llvm::formatv("Can't store {0} value {1} in integer with {2} " - "bits.", - (is_unsigned ? "unsigned" : "signed"), - value_as_str, type_bits); - return llvm::createStringError(llvm::inconvertibleErrorCode(), msg.str()); - } - - // Trim the result to the bit width our the int type. - if (result.getBitWidth() > type_bits) - result = result.trunc(type_bits); - return result; -} - void DWARFASTParserClang::ParseSingleMember( const DWARFDIE &die, const DWARFDIE &parent_die, const lldb_private::CompilerType &class_clang_type, lldb::AccessType default_accessibility, lldb_private::ClangASTImporter::LayoutInfo &layout_info, FieldInfo &last_field_info) { - Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); // This function can only parse DW_TAG_member. assert(die.Tag() == DW_TAG_member); @@ -2680,27 +2623,9 @@ void DWARFASTParserClang::ParseSingleMember( if (var_type) { if (attrs.accessibility == eAccessNone) attrs.accessibility = eAccessPublic; - CompilerType ct = var_type->GetForwardCompilerType(); - clang::VarDecl *v = TypeSystemClang::AddVariableToRecordType( - class_clang_type, attrs.name, ct, attrs.accessibility); - if (!v) { - LLDB_LOG(log, "Failed to add variable to the record type"); - return; - } - - bool unused; - // TODO: Support float/double static members as well. - if (!attrs.const_value_form || !ct.IsIntegerOrEnumerationType(unused)) - return; - llvm::Expected<llvm::APInt> const_value_or_err = - ExtractIntFromFormValue(ct, *attrs.const_value_form); - if (!const_value_or_err) { - LLDB_LOG_ERROR(log, const_value_or_err.takeError(), - "Failed to add const value to variable {1}: {0}", - v->getQualifiedNameAsString()); - return; - } - TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err); + TypeSystemClang::AddVariableToRecordType( + class_clang_type, attrs.name, var_type->GetForwardCompilerType(), + attrs.accessibility); } return; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 733ffa230f1e8..f97c0c470ab07 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -68,22 +68,6 @@ class DWARFASTParserClang : public DWARFASTParser { lldb_private::ClangASTImporter &GetClangASTImporter(); - /// Extracts an value for a given Clang integer type from a DWARFFormValue. - /// - /// \param int_type The Clang type that defines the bit size and signedness - /// of the integer that should be extracted. Has to be either - /// an integer type or an enum type. For enum types the - /// underlying integer type will be considered as the - /// expected integer type that should be extracted. - /// \param form_value The DWARFFormValue that contains the integer value. - /// \return An APInt containing the same integer value as the given - /// DWARFFormValue with the bit width of the given integer type. - /// Returns an error if the value in the DWARFFormValue does not fit - /// into the given integer type or the integer type isn't supported. - llvm::Expected<llvm::APInt> - ExtractIntFromFormValue(const lldb_private::CompilerType &int_type, - const DWARFFormValue &form_value) const; - protected: /// Protected typedefs and members. /// @{ diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/Makefile b/lldb/test/API/lang/cpp/const_static_integral_member/Makefile deleted file mode 100644 index 99998b20bcb05..0000000000000 --- a/lldb/test/API/lang/cpp/const_static_integral_member/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -CXX_SOURCES := main.cpp - -include Makefile.rules diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py deleted file mode 100644 index 86db78187aa82..0000000000000 --- a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -Tests const static data members as specified by C++11 [class.static.data]p3. -""" - -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - -class TestCase(TestBase): - - mydir = TestBase.compute_mydir(__file__) - - def test(self): - self.build() - lldbutil.run_to_source_breakpoint(self, "// break here", - lldb.SBFileSpec("main.cpp")) - - # Test using a simple const static integer member. - self.expect_expr("A::int_val", result_value="1") - - # Try accessing the int member via some expressions that still produce - # an lvalue. - self.expect_expr("a.int_val", result_value="1") - self.expect_expr("(A::int_val)", result_value="1") - self.expect_expr("+A::int_val", result_value="1") - self.expect_expr("1,A::int_val", result_value="1") - self.expect_expr("true ? A::int_val : A::int_val", result_value="1") - - # Test a simple integer member that was also defined in a namespace - # scope and has an address. - self.expect_expr("A::int_val_with_address", result_value="2") - - # Try to take the address of the data member. Should produce a linker - # error only if the member doesn't have an address. - self.expect("expr const int *i = &A::int_val; *i", error=True, - substrs=["Couldn't lookup symbols:"]) - self.expect_expr("const int *i = &A::int_val_with_address; *i", - result_value="2") - - # Test a bool member. - self.expect_expr("A::bool_val", result_value="true") - - # Test that minimum and maximum values for each data type are right. - self.expect_expr("A::char_max == char_max", result_value="true") - self.expect_expr("A::uchar_max == uchar_max", result_value="true") - self.expect_expr("A::int_max == int_max", result_value="true") - self.expect_expr("A::uint_max == uint_max", result_value="true") - self.expect_expr("A::long_max == long_max", result_value="true") - self.expect_expr("A::ulong_max == ulong_max", result_value="true") - self.expect_expr("A::longlong_max == longlong_max", result_value="true") - self.expect_expr("A::ulonglong_max == ulonglong_max", result_value="true") - - self.expect_expr("A::char_min == char_min", result_value="true") - self.expect_expr("A::uchar_min == uchar_min", result_value="true") - self.expect_expr("A::int_min == int_min", result_value="true") - self.expect_expr("A::uint_min == uint_min", result_value="true") - self.expect_expr("A::long_min == long_min", result_value="true") - self.expect_expr("A::ulong_min == ulong_min", result_value="true") - self.expect_expr("A::longlong_min == longlong_min", result_value="true") - self.expect_expr("A::ulonglong_min == ulonglong_min", result_value="true") - - # Test an unscoped enum. - self.expect_expr("A::enum_val", result_value="enum_case2") - # Test an unscoped enum with an invalid enum case. - self.expect_expr("A::invalid_enum_val", result_value="enum_case1 | enum_case2 | 0x4") - - # Test a scoped enum. - self.expect_expr("A::scoped_enum_val", result_value="scoped_enum_case2") - # Test an scoped enum with an invalid enum case. - self.expect_expr("A::invalid_scoped_enum_val", result_value="scoped_enum_case1 | 0x4") - - # Test an enum with fixed underlying type. - self.expect_expr("A::scoped_char_enum_val", result_value="case2") - self.expect_expr("A::scoped_ll_enum_val_neg", result_value="case0") - self.expect_expr("A::scoped_ll_enum_val", result_value="case2") - - # Try to take the address of a member that doesn't have one. - self.expect("expr const int *i = &A::int_val; *i", error=True, - substrs=["Couldn't lookup symbols:"]) - - # dsymutil strips the debug info for classes that only have const static - # data members without a definition namespace scope. - @expectedFailureAll(debug_info=["dsym"]) - def test_class_with_only_const_static(self): - self.build() - lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.cpp")) - - self.expect_expr("ClassWithOnlyConstStatic::member", result_value="3") - - # Test `constexpr static`. - self.expect_expr("ClassWithConstexprs::member", result_value="2") - self.expect_expr("ClassWithConstexprs::enum_val", result_value="enum_case2") - self.expect_expr("ClassWithConstexprs::scoped_enum_val", result_value="scoped_enum_case2") diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp deleted file mode 100644 index 9762424f2345c..0000000000000 --- a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include <limits> - -enum Enum { - enum_case1 = 1, - enum_case2 = 2, -}; - -enum class ScopedEnum { - scoped_enum_case1 = 1, - scoped_enum_case2 = 2, -}; - -enum class ScopedCharEnum : char { - case1 = 1, - case2 = 2, -}; - -enum class ScopedLongLongEnum : long long { - case0 = std::numeric_limits<long long>::min(), - case1 = 1, - case2 = std::numeric_limits<long long>::max(), -}; - -struct A { - const static int int_val = 1; - const static int int_val_with_address = 2; - const static bool bool_val = true; - - const static auto char_max = std::numeric_limits<signed char>::max(); - const static auto uchar_max = std::numeric_limits<unsigned char>::max(); - const static auto int_max = std::numeric_limits<int>::max(); - const static auto uint_max = std::numeric_limits<unsigned>::max(); - const static auto long_max = std::numeric_limits<long>::max(); - const static auto ulong_max = std::numeric_limits<unsigned long>::max(); - const static auto longlong_max = std::numeric_limits<long long>::max(); - const static auto ulonglong_max = - std::numeric_limits<unsigned long long>::max(); - - const static auto char_min = std::numeric_limits<char>::min(); - const static auto uchar_min = std::numeric_limits<unsigned char>::min(); - const static auto int_min = std::numeric_limits<int>::min(); - const static auto uint_min = std::numeric_limits<unsigned>::min(); - const static auto long_min = std::numeric_limits<long>::min(); - const static auto ulong_min = std::numeric_limits<unsigned long>::min(); - const static auto longlong_min = std::numeric_limits<long long>::min(); - const static auto ulonglong_min = - std::numeric_limits<unsigned long long>::min(); - - const static Enum enum_val = enum_case2; - const static Enum invalid_enum_val = static_cast<Enum>(enum_case2 + 5); - const static ScopedEnum scoped_enum_val = ScopedEnum::scoped_enum_case2; - const static ScopedEnum invalid_scoped_enum_val = static_cast<ScopedEnum>(5); - const static ScopedCharEnum scoped_char_enum_val = ScopedCharEnum::case2; - const static ScopedLongLongEnum scoped_ll_enum_val_neg = - ScopedLongLongEnum::case0; - const static ScopedLongLongEnum scoped_ll_enum_val = - ScopedLongLongEnum::case2; -}; - -const int A::int_val_with_address; - -struct ClassWithOnlyConstStatic { - const static int member = 3; -}; - -struct ClassWithConstexprs { - constexpr static int member = 2; - constexpr static Enum enum_val = enum_case2; - constexpr static ScopedEnum scoped_enum_val = ScopedEnum::scoped_enum_case2; -} cwc; - -int main() { - A a; - - auto char_max = A::char_max; - auto uchar_max = A::uchar_max; - auto int_max = A::int_max; - auto uint_max = A::uint_max; - auto long_max = A::long_max; - auto ulong_max = A::ulong_max; - auto longlong_max = A::longlong_max; - auto ulonglong_max = A::ulonglong_max; - - auto char_min = A::char_min; - auto uchar_min = A::uchar_min; - auto int_min = A::int_min; - auto uint_min = A::uint_min; - auto long_min = A::long_min; - auto ulong_min = A::ulong_min; - auto longlong_min = A::longlong_min; - auto ulonglong_min = A::ulonglong_min; - - int member_copy = ClassWithOnlyConstStatic::member; - - Enum e = A::enum_val; - e = A::invalid_enum_val; - ScopedEnum se = A::scoped_enum_val; - se = A::invalid_scoped_enum_val; - ScopedCharEnum sce = A::scoped_char_enum_val; - ScopedLongLongEnum sle = A::scoped_ll_enum_val; - return 0; // break here -} diff --git a/lldb/test/API/lang/cpp/const_static_integral_member_int128/Makefile b/lldb/test/API/lang/cpp/const_static_integral_member_int128/Makefile deleted file mode 100644 index 99998b20bcb05..0000000000000 --- a/lldb/test/API/lang/cpp/const_static_integral_member_int128/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -CXX_SOURCES := main.cpp - -include Makefile.rules diff --git a/lldb/test/API/lang/cpp/const_static_integral_member_int128/TestConstStaticIntegralMemberInt128.py b/lldb/test/API/lang/cpp/const_static_integral_member_int128/TestConstStaticIntegralMemberInt128.py deleted file mode 100644 index edf5383340400..0000000000000 --- a/lldb/test/API/lang/cpp/const_static_integral_member_int128/TestConstStaticIntegralMemberInt128.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Tests const static data members as specified by C++11 [class.static.data]p3 -with (u)int128_t types. -""" - -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - -class TestCase(TestBase): - - mydir = TestBase.compute_mydir(__file__) - - def test_int128(self): - self.build() - lldbutil.run_to_source_breakpoint(self, "// break here", - lldb.SBFileSpec("main.cpp")) - - # Try to use the (u)int128_t data members which are not supported at - # the moment. Just verify that LLDB doesn't report an incorrect value - # for them and just treats them as normal variables (which will lead - # to linker errors as they are not defined anywhere). - self.expect("expr A::int128_max", error=True, - substrs=["Couldn't lookup symbols:"]) - self.expect("expr A::uint128_max", error=True, - substrs=["Couldn't lookup symbols:"]) - self.expect("expr A::int128_min", error=True, - substrs=["Couldn't lookup symbols:"]) - self.expect("expr A::uint128_min", error=True, - substrs=["Couldn't lookup symbols:"]) diff --git a/lldb/test/API/lang/cpp/const_static_integral_member_int128/main.cpp b/lldb/test/API/lang/cpp/const_static_integral_member_int128/main.cpp deleted file mode 100644 index bac996d5f66d5..0000000000000 --- a/lldb/test/API/lang/cpp/const_static_integral_member_int128/main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include <limits> - -struct A { - const static auto uint128_max = std::numeric_limits<__uint128_t>::max(); - const static auto uint128_min = std::numeric_limits<__uint128_t>::min(); - const static auto int128_max = std::numeric_limits<__int128_t>::max(); - const static auto int128_min = std::numeric_limits<__int128_t>::min(); -}; - -int main() { - A a; - - auto int128_max = A::int128_max; - auto uint128_max = A::uint128_max; - auto int128_min = A::int128_min; - auto uint128_min = A::uint128_min; - return 0; // break here -} diff --git a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt index 6af866153a138..16c38c4ab2190 100644 --- a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -17,7 +17,6 @@ add_lldb_unittest(SymbolFileDWARFTests lldbPluginPlatformMacOSX lldbUtilityHelpers lldbSymbolHelpers - LLVMTestingSupport LINK_COMPONENTS Support DebugInfoPDB diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp index d7d8519d6c87c..ed46db8e6be6c 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -273,128 +273,3 @@ TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) { }; ASSERT_EQ(found_function_types, expected_function_types); } - -struct ExtractIntFromFormValueTest : public testing::Test { - SubsystemRAII<FileSystem, HostInfo> subsystems; - TypeSystemClang ts; - DWARFASTParserClang parser; - ExtractIntFromFormValueTest() - : ts("dummy ASTContext", HostInfoBase::GetTargetTriple()), parser(ts) {} - - /// Takes the given integer value, stores it in a DWARFFormValue and then - /// tries to extract the value back via - /// DWARFASTParserClang::ExtractIntFromFormValue. - /// Returns the string representation of the extracted value or the error - /// that was returned from ExtractIntFromFormValue. - llvm::Expected<std::string> Extract(clang::QualType qt, uint64_t value) { - DWARFFormValue form_value; - form_value.SetUnsigned(value); - llvm::Expected<llvm::APInt> result = - parser.ExtractIntFromFormValue(ts.GetType(qt), form_value); - if (!result) - return result.takeError(); - llvm::SmallString<16> result_str; - result->toStringUnsigned(result_str); - return std::string(result_str.str()); - } - - /// Same as ExtractIntFromFormValueTest::Extract but takes a signed integer - /// and treats the result as a signed integer. - llvm::Expected<std::string> ExtractS(clang::QualType qt, int64_t value) { - DWARFFormValue form_value; - form_value.SetSigned(value); - llvm::Expected<llvm::APInt> result = - parser.ExtractIntFromFormValue(ts.GetType(qt), form_value); - if (!result) - return result.takeError(); - llvm::SmallString<16> result_str; - result->toStringSigned(result_str); - return std::string(result_str.str()); - } -}; - -TEST_F(ExtractIntFromFormValueTest, TestBool) { - using namespace llvm; - clang::ASTContext &ast = ts.getASTContext(); - - EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 0), HasValue("0")); - EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 1), HasValue("1")); - EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 2), Failed()); - EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 3), Failed()); -} - -TEST_F(ExtractIntFromFormValueTest, TestInt) { - using namespace llvm; - - clang::ASTContext &ast = ts.getASTContext(); - - // Find the min/max values for 'int' on the current host target. - constexpr int64_t int_max = std::numeric_limits<int>::max(); - constexpr int64_t int_min = std::numeric_limits<int>::min(); - - // Check that the bit width of int matches the int width in our type system. - ASSERT_EQ(sizeof(int) * 8, ast.getIntWidth(ast.IntTy)); - - // Check values around int_min. - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min - 2), llvm::Failed()); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min - 1), llvm::Failed()); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min), - HasValue(std::to_string(int_min))); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min + 1), - HasValue(std::to_string(int_min + 1))); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min + 2), - HasValue(std::to_string(int_min + 2))); - - // Check values around 0. - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, -128), HasValue("-128")); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, -10), HasValue("-10")); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, -1), HasValue("-1")); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 0), HasValue("0")); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 1), HasValue("1")); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 10), HasValue("10")); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 128), HasValue("128")); - - // Check values around int_max. - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max - 2), - HasValue(std::to_string(int_max - 2))); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max - 1), - HasValue(std::to_string(int_max - 1))); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max), - HasValue(std::to_string(int_max))); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max + 1), llvm::Failed()); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max + 5), llvm::Failed()); - - // Check some values not near an edge case. - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max / 2), - HasValue(std::to_string(int_max / 2))); - EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min / 2), - HasValue(std::to_string(int_min / 2))); -} - -TEST_F(ExtractIntFromFormValueTest, TestUnsignedInt) { - using namespace llvm; - - clang::ASTContext &ast = ts.getASTContext(); - constexpr uint64_t uint_max = std::numeric_limits<uint32_t>::max(); - - // Check values around 0. - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, 0), HasValue("0")); - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, 1), HasValue("1")); - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, 1234), HasValue("1234")); - - // Check some values not near an edge case. - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max / 2), - HasValue(std::to_string(uint_max / 2))); - - // Check values around uint_max. - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max - 2), - HasValue(std::to_string(uint_max - 2))); - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max - 1), - HasValue(std::to_string(uint_max - 1))); - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max), - HasValue(std::to_string(uint_max))); - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max + 1), - llvm::Failed()); - EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max + 2), - llvm::Failed()); -} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits