[Lldb-commits] [lldb] r342421 - [DataFormatters] Add formatter for C++17 std::variant

Davide Italiano via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 17 15:57:10 PDT 2018


I'm afraid this broke one of our bots. Can you please take a look and
fix or revert?

Thanks!

Testing Time: 236.25s
********************
Failing Tests (1):
    lldb-Suite ::
functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py


http://green.lab.llvm.org/green/job/lldb-cmake-clang-5.0.2//418/console
On Mon, Sep 17, 2018 at 3:11 PM Shafik Yaghmour via lldb-commits
<lldb-commits at lists.llvm.org> wrote:
>
> Author: shafik
> Date: Mon Sep 17 15:10:44 2018
> New Revision: 342421
>
> URL: http://llvm.org/viewvc/llvm-project?rev=342421&view=rev
> Log:
> [DataFormatters] Add formatter for C++17 std::variant
>
> rdar://problem/43691454
>
> Patch by Shafik Yaghmour.
>
> Differential Revision: https://reviews.llvm.org/D51520
>
> Added:
>     lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/
>     lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile
>     lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py
>     lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp
>     lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
>     lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.h
> Modified:
>     lldb/trunk/lldb.xcodeproj/project.pbxproj
>     lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt
>     lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
>     lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h
>
> Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=342421&r1=342420&r2=342421&view=diff
> ==============================================================================
> --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
> +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Sep 17 15:10:44 2018
> @@ -401,6 +401,8 @@
>                 AF9FF1F71FAA79FE00474976 /* LibCxxQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */; };
>                 AF9FF1F51FAA79A400474976 /* LibCxxTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */; };
>                 945261C41B9A11FC00BF138D /* LibCxxUnorderedMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */; };
> +               E414F6F121388F6C00C50BC6 /* LibCxxVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E414F6F021388F6B00C50BC6 /* LibCxxVariant.cpp */; };
> +               E414F6EE21388F0300C50BC6 /* LibCxxVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = E414F6ED21388F0200C50BC6 /* LibCxxVariant.h */; };
>                 945261C51B9A11FC00BF138D /* LibCxxVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261BB1B9A11E800BF138D /* LibCxxVector.cpp */; };
>                 945261C61B9A11FC00BF138D /* LibStdcpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261BC1B9A11E800BF138D /* LibStdcpp.cpp */; };
>                 4CDB8D6E1DBA91B6006C5B13 /* LibStdcppTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CDB8D681DBA91A6006C5B13 /* LibStdcppTuple.cpp */; };
> @@ -2056,6 +2058,8 @@
>                 AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxQueue.cpp; path = Language/CPlusPlus/LibCxxQueue.cpp; sourceTree = "<group>"; };
>                 AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxTuple.cpp; path = Language/CPlusPlus/LibCxxTuple.cpp; sourceTree = "<group>"; };
>                 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxUnorderedMap.cpp; path = Language/CPlusPlus/LibCxxUnorderedMap.cpp; sourceTree = "<group>"; };
> +               E414F6F021388F6B00C50BC6 /* LibCxxVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxVariant.cpp; path = Language/CPlusPlus/LibCxxVariant.cpp; sourceTree = "<group>"; };
> +               E414F6ED21388F0200C50BC6 /* LibCxxVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibCxxVariant.h; path = Language/CPlusPlus/LibCxxVariant.h; sourceTree = "<group>"; };
>                 945261BB1B9A11E800BF138D /* LibCxxVector.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxVector.cpp; path = Language/CPlusPlus/LibCxxVector.cpp; sourceTree = "<group>"; };
>                 945261BC1B9A11E800BF138D /* LibStdcpp.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibStdcpp.cpp; path = Language/CPlusPlus/LibStdcpp.cpp; sourceTree = "<group>"; };
>                 945261BD1B9A11E800BF138D /* LibStdcpp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LibStdcpp.h; path = Language/CPlusPlus/LibStdcpp.h; sourceTree = "<group>"; };
> @@ -6475,6 +6479,8 @@
>                                 AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */,
>                                 AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */,
>                                 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */,
> +                               E414F6ED21388F0200C50BC6 /* LibCxxVariant.h */,
> +                               E414F6F021388F6B00C50BC6 /* LibCxxVariant.cpp */,
>                                 945261BB1B9A11E800BF138D /* LibCxxVector.cpp */,
>                                 945261BD1B9A11E800BF138D /* LibStdcpp.h */,
>                                 945261BC1B9A11E800BF138D /* LibStdcpp.cpp */,
> @@ -7081,6 +7087,7 @@
>                                 6D0F614F1C80AB0C00A4ECEE /* JavaLanguageRuntime.h in Headers */,
>                                 AF27AD561D3603EA00CF2833 /* DynamicLoaderDarwin.h in Headers */,
>                                 AFCB2BBE1BF577F40018B553 /* PythonExceptionState.h in Headers */,
> +                               E414F6EE21388F0300C50BC6 /* LibCxxVariant.h in Headers */,
>                                 267F684B1CC02DED0086832B /* ABISysV_s390x.h in Headers */,
>                                 AF8AD6311BEC28A400150209 /* PlatformAppleWatchSimulator.h in Headers */,
>                         );
> @@ -7936,6 +7943,7 @@
>                                 AF0C112818580CD800C4C45B /* QueueItem.cpp in Sources */,
>                                 AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */,
>                                 2689004913353E0400698AC0 /* Scalar.cpp in Sources */,
> +                               E414F6F121388F6C00C50BC6 /* LibCxxVariant.cpp in Sources */,
>                                 263FDE601A79A01500E68013 /* FormatEntity.cpp in Sources */,
>                                 AF8AD62E1BEC28A400150209 /* PlatformAppleTVSimulator.cpp in Sources */,
>                                 2689004A13353E0400698AC0 /* SearchFilter.cpp in Sources */,
>
> Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile?rev=342421&view=auto
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile (added)
> +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile Mon Sep 17 15:10:44 2018
> @@ -0,0 +1,7 @@
> +LEVEL = ../../../../../make
> +
> +CXX_SOURCES := main.cpp
> +
> +USE_LIBCPP := 1
> +include $(LEVEL)/Makefile.rules
> +CXXFLAGS += -std=c++17
>
> Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py?rev=342421&view=auto
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py (added)
> +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py Mon Sep 17 15:10:44 2018
> @@ -0,0 +1,81 @@
> +"""
> +Test lldb data formatter subsystem.
> +"""
> +
> +from __future__ import print_function
> +
> +
> +import os
> +import time
> +import lldb
> +from lldbsuite.test.decorators import *
> +from lldbsuite.test.lldbtest import *
> +from lldbsuite.test import lldbutil
> +
> +class LibcxxOptionalDataFormatterTestCase(TestBase):
> +
> +    mydir = TestBase.compute_mydir(__file__)
> +
> +    @add_test_categories(["libc++"])
> +    ## We are skipping clang version less that 5.0 since this test requires -std=c++17
> +    @skipIf(oslist=no_match(["macosx"]), compiler="clang", compiler_version=['<', '5.0'])
> +    ## We are skipping gcc version less that 5.1 since this test requires -std=c++17
> +    @skipIf(compiler="gcc", compiler_version=['<', '5.1'])
> +
> +    def test_with_run_command(self):
> +        """Test that that file and class static variables display correctly."""
> +        self.build()
> +
> +        (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
> +                lldb.SBFileSpec("main.cpp", False))
> +
> +        self.runCmd( "frame variable has_variant" )
> +
> +        output = self.res.GetOutput()
> +
> +        ## The variable has_variant tells us if the test program
> +        ## detected we have a sufficient libc++ version to support variant
> +        ## false means we do not and therefore should skip the test
> +        if output.find("(bool) has_variant = false") != -1 :
> +            self.skipTest( "std::variant not supported" )
> +
> +        lldbutil.continue_to_breakpoint(self.process, bkpt)
> +
> +        self.expect("frame variable v1",
> +                substrs=['v1 =  Active Type = int  {',
> +                               'Value = 12',
> +                               '}'])
> +
> +        self.expect("frame variable v1_ref",
> +                substrs=['v1_ref =  Active Type = int : {',
> +                               'Value = 12',
> +                               '}'])
> +
> +        self.expect("frame variable v_v1",
> +                substrs=['v_v1 =  Active Type = std::__1::variant<int, double, char>  {',
> +                                 'Value =  Active Type = int  {',
> +                                   'Value = 12',
> +                                 '}',
> +                               '}'])
> +
> +        lldbutil.continue_to_breakpoint(self.process, bkpt)
> +
> +        self.expect("frame variable v1",
> +                substrs=['v1 =  Active Type = double  {',
> +                               'Value = 2',
> +                               '}'])
> +
> +        lldbutil.continue_to_breakpoint(self.process, bkpt)
> +
> +        self.expect("frame variable v2",
> +                substrs=['v2 =  Active Type = double  {',
> +                               'Value = 2',
> +                               '}'])
> +
> +        self.expect("frame variable v3",
> +                substrs=['v3 =  Active Type = char  {',
> +                               'Value = \'A\'',
> +                               '}'])
> +
> +        self.expect("frame variable v_no_value",
> +                    substrs=['v_no_value =  No Value'])
>
> Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp?rev=342421&view=auto
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp (added)
> +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp Mon Sep 17 15:10:44 2018
> @@ -0,0 +1,60 @@
> +#include <cstdio>
> +#include <string>
> +#include <vector>
> +
> +// If we have libc++ 4.0 or greater we should have <variant>
> +// According to libc++ C++1z status page https://libcxx.llvm.org/cxx1z_status.html
> +#if _LIBCPP_VERSION >= 4000
> +#include <variant>
> +#define HAVE_VARIANT 1
> +#else
> +#define HAVE_VARIANT 0
> +#endif
> +
> +struct S {
> +  operator int() { throw 42; }
> +} ;
> +
> +
> +int main()
> +{
> +    bool has_variant = HAVE_VARIANT ;
> +
> +    printf( "%d\n", has_variant ) ; // break here
> +
> +#if HAVE_VARIANT == 1
> +    std::variant<int, double, char> v1;
> +    std::variant<int, double, char> &v1_ref = v1;
> +    std::variant<int, double, char> v2;
> +    std::variant<int, double, char> v3;
> +    std::variant<std::variant<int,double,char>> v_v1 ;
> +    std::variant<int, double, char> v_no_value;
> +
> +    v1 = 12; // v contains int
> +    v_v1 = v1 ;
> +    int i = std::get<int>(v1);
> +    printf( "%d\n", i ); // break here
> +
> +    v2 = 2.0 ;
> +    double d = std::get<double>(v2) ;
> +    printf( "%f\n", d );
> +
> +    v3 = 'A' ;
> +    char c = std::get<char>(v3) ;
> +    printf( "%d\n", c );
> +
> +    // Checking v1 above and here to make sure we done maintain the incorrect
> +    // state when we change its value.
> +    v1 = 2.0;
> +    d = std::get<double>(v1) ;
> +    printf( "%f\n", d ); // break here
> +
> +     try {
> +       v_no_value.emplace<0>(S());
> +     } catch( ... ) {}
> +
> +     printf( "%zu\n", v_no_value.index() ) ;
> +#endif
> +
> +    return 0; // break here
> +}
>
> Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt?rev=342421&r1=342420&r2=342421&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt (original)
> +++ lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt Mon Sep 17 15:10:44 2018
> @@ -13,6 +13,7 @@ add_lldb_library(lldbPluginCPlusPlusLang
>    LibCxxQueue.cpp
>    LibCxxTuple.cpp
>    LibCxxUnorderedMap.cpp
> +  LibCxxVariant.cpp
>    LibCxxVector.cpp
>    LibStdcpp.cpp
>    LibStdcppTuple.cpp
>
> Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp?rev=342421&r1=342420&r2=342421&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (original)
> +++ lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp Mon Sep 17 15:10:44 2018
> @@ -39,6 +39,7 @@
>  #include "CxxStringTypes.h"
>  #include "LibCxx.h"
>  #include "LibCxxAtomic.h"
> +#include "LibCxxVariant.h"
>  #include "LibStdcpp.h"
>
>  using namespace lldb;
> @@ -516,6 +517,10 @@ static void LoadLibCxxFormatters(lldb::T
>                    "libc++ std::optional synthetic children",
>                    ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"),
>                    stl_synth_flags, true);
> +  AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
> +                  "libc++ std::variant synthetic children",
> +                  ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"),
> +                  stl_synth_flags, true);
>    AddCXXSynthetic(
>        cpp_category_sp,
>        lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
> @@ -617,6 +622,11 @@ static void LoadLibCxxFormatters(lldb::T
>                  "libc++ std::optional summary provider",
>                  ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"),
>                  stl_summary_flags, true);
> +  AddCXXSummary(cpp_category_sp,
> +                lldb_private::formatters::LibcxxVariantSummaryProvider,
> +                "libc++ std::variant summary provider",
> +                ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"),
> +                stl_summary_flags, true);
>
>    stl_summary_flags.SetSkipPointers(true);
>
>
> Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h?rev=342421&r1=342420&r2=342421&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h (original)
> +++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h Mon Sep 17 15:10:44 2018
> @@ -142,6 +142,10 @@ SyntheticChildrenFrontEnd *
>  LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *,
>                                lldb::ValueObjectSP valobj_sp);
>
> +SyntheticChildrenFrontEnd *
> +LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
> +                             lldb::ValueObjectSP valobj_sp);
> +
>  } // namespace formatters
>  } // namespace lldb_private
>
>
> Added: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp?rev=342421&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp (added)
> +++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp Mon Sep 17 15:10:44 2018
> @@ -0,0 +1,273 @@
> +//===-- LibCxxVariant.cpp --------------------------------------*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "LibCxxVariant.h"
> +#include "lldb/DataFormatters/FormattersHelpers.h"
> +
> +#include "llvm/ADT/Optional.h"
> +#include "llvm/ADT/ScopeExit.h"
> +
> +using namespace lldb;
> +using namespace lldb_private;
> +
> +// libc++ variant implementation contains two members that we care about both
> +// are contained in the __impl member.
> +// - __index which tells us which of the variadic template types is the active
> +//   type for the variant
> +// - __data is a variadic union which recursively contains itself as member
> +//   which refers to the tailing variadic types.
> +//   - __head which refers to the leading non pack type
> +//     - __value refers to the actual value contained
> +//   - __tail which refers to the remaining pack types
> +//
> +// e.g. given std::variant<int,double,char> v1
> +//
> +// (lldb) frame var -R v1.__impl.__data
> +//(... __union<... 0, int, double, char>) v1.__impl.__data = {
> +// ...
> +//  __head = {
> +//    __value = ...
> +//  }
> +//  __tail = {
> +//  ...
> +//    __head = {
> +//      __value = ...
> +//    }
> +//    __tail = {
> +//    ...
> +//      __head = {
> +//        __value = ...
> +//  ...
> +//
> +// So given
> +// - __index equal to 0 the active value is contained in
> +//
> +//     __data.__head.__value
> +//
> +// - __index equal to 1 the active value is contained in
> +//
> +//     __data.__tail.__head.__value
> +//
> +// - __index equal to 2 the active value is contained in
> +//
> +//      __data.__tail.__tail.__head.__value
> +//
> +
> +namespace {
> +// libc++ std::variant index could have one of three states
> +// 1) VALID, we can obtain it and its not variant_npos
> +// 2) INVALID, we can't obtain it or it is not a type we expect
> +// 3) NPOS, its value is variant_npos which means the variant has no value
> +enum class LibcxxVariantIndexValidity { VALID, INVALID, NPOS };
> +
> +LibcxxVariantIndexValidity
> +LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) {
> +  ValueObjectSP index_sp(
> +      impl_sp->GetChildMemberWithName(ConstString("__index"), true));
> +
> +  if (!index_sp)
> +    return LibcxxVariantIndexValidity::INVALID;
> +
> +  int64_t index_value = index_sp->GetValueAsSigned(0);
> +
> +  CompilerType index_compiler_type = index_sp->GetCompilerType();
> +
> +  // We are expecting two layers of typedefs before we obtain the basic type
> +  // The next two checks verify this.
> +  if (!index_compiler_type.IsTypedefType())
> +    return LibcxxVariantIndexValidity::INVALID;
> +
> +  if (!index_compiler_type.GetTypedefedType().IsTypedefType())
> +    return LibcxxVariantIndexValidity::INVALID;
> +
> +  lldb::BasicType index_basic_type = index_compiler_type.GetTypedefedType()
> +                                         .GetTypedefedType()
> +                                         .GetBasicTypeEnumeration();
> +
> +  if (index_basic_type == eBasicTypeInvalid)
> +    return LibcxxVariantIndexValidity::INVALID;
> +
> +  if (index_value == -1)
> +    return LibcxxVariantIndexValidity::NPOS;
> +
> +  return LibcxxVariantIndexValidity::VALID;
> +}
> +
> +llvm::Optional<uint64_t> LibcxxVariantIndexValue(ValueObjectSP &impl_sp) {
> +  ValueObjectSP index_sp(
> +      impl_sp->GetChildMemberWithName(ConstString("__index"), true));
> +
> +  if (!index_sp)
> +    return {};
> +
> +  return {index_sp->GetValueAsUnsigned(0)};
> +}
> +
> +ValueObjectSP LibcxxVariantGetNthHead(ValueObjectSP &impl_sp, uint64_t index) {
> +  ValueObjectSP data_sp(
> +      impl_sp->GetChildMemberWithName(ConstString("__data"), true));
> +
> +  if (!data_sp)
> +    return ValueObjectSP{};
> +
> +  ValueObjectSP current_level = data_sp;
> +  for (uint64_t n = index; n != 0; --n) {
> +    ValueObjectSP tail_sp(
> +        current_level->GetChildMemberWithName(ConstString("__tail"), true));
> +
> +    if (!tail_sp)
> +      return ValueObjectSP{};
> +
> +    current_level = tail_sp;
> +  }
> +
> +  return current_level->GetChildMemberWithName(ConstString("__head"), true);
> +};
> +} // namespace
> +
> +namespace lldb_private {
> +namespace formatters {
> +bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream,
> +                                  const TypeSummaryOptions &options) {
> +  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
> +  if (!valobj_sp)
> +    return false;
> +
> +  ValueObjectSP impl_sp(
> +      valobj_sp->GetChildMemberWithName(ConstString("__impl"), true));
> +
> +  if (!impl_sp)
> +    return false;
> +
> +  LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp);
> +
> +  if (validity == LibcxxVariantIndexValidity::INVALID)
> +    return false;
> +
> +  if (validity == LibcxxVariantIndexValidity::NPOS) {
> +    stream.Printf(" No Value");
> +    return true;
> +  }
> +
> +  auto optional_index_value = LibcxxVariantIndexValue(impl_sp);
> +
> +  if (!optional_index_value)
> +    return false;
> +
> +  uint64_t index_value = *optional_index_value;
> +
> +  ValueObjectSP nth_head = LibcxxVariantGetNthHead(impl_sp, index_value);
> +
> +  if (!nth_head)
> +    return false;
> +
> +  CompilerType head_type = nth_head->GetCompilerType();
> +
> +  if (!head_type)
> +    return false;
> +
> +  CompilerType template_type = head_type.GetTypeTemplateArgument(1);
> +
> +  if (!template_type)
> +    return false;
> +
> +  stream.Printf(" Active Type = %s ", template_type.GetTypeName().GetCString());
> +
> +  return true;
> +}
> +} // namespace formatters
> +} // namespace lldb_private
> +
> +namespace {
> +class VariantFrontEnd : public SyntheticChildrenFrontEnd {
> +public:
> +  VariantFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
> +    Update();
> +  }
> +
> +  size_t GetIndexOfChildWithName(const ConstString &name) override {
> +    return formatters::ExtractIndexFromString(name.GetCString());
> +  }
> +
> +  bool MightHaveChildren() override { return true; }
> +  bool Update() override;
> +  size_t CalculateNumChildren() override { return m_size; }
> +  ValueObjectSP GetChildAtIndex(size_t idx) override;
> +
> +private:
> +  size_t m_size = 0;
> +  ValueObjectSP m_base_sp;
> +};
> +} // namespace
> +
> +bool VariantFrontEnd::Update() {
> +  m_size = 0;
> +  ValueObjectSP impl_sp(
> +      m_backend.GetChildMemberWithName(ConstString("__impl"), true));
> +  if (!impl_sp)
> +    return false;
> +
> +  LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp);
> +
> +  if (validity == LibcxxVariantIndexValidity::INVALID)
> +    return false;
> +
> +  if (validity == LibcxxVariantIndexValidity::NPOS)
> +    return true;
> +
> +  m_size = 1;
> +
> +  return false;
> +}
> +
> +ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) {
> +  if (idx >= m_size)
> +    return ValueObjectSP();
> +
> +  ValueObjectSP impl_sp(
> +      m_backend.GetChildMemberWithName(ConstString("__impl"), true));
> +
> +  auto optional_index_value = LibcxxVariantIndexValue(impl_sp);
> +
> +  if (!optional_index_value)
> +    return ValueObjectSP();
> +
> +  uint64_t index_value = *optional_index_value;
> +
> +  ValueObjectSP nth_head = LibcxxVariantGetNthHead(impl_sp, index_value);
> +
> +  if (!nth_head)
> +    return ValueObjectSP();
> +
> +  CompilerType head_type = nth_head->GetCompilerType();
> +
> +  if (!head_type)
> +    return ValueObjectSP();
> +
> +  CompilerType template_type = head_type.GetTypeTemplateArgument(1);
> +
> +  if (!template_type)
> +    return ValueObjectSP();
> +
> +  ValueObjectSP head_value(
> +      nth_head->GetChildMemberWithName(ConstString("__value"), true));
> +
> +  if (!head_value)
> +    return ValueObjectSP();
> +
> +  return head_value->Clone(ConstString(ConstString("Value").AsCString()));
> +}
> +
> +SyntheticChildrenFrontEnd *
> +formatters::LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
> +                                         lldb::ValueObjectSP valobj_sp) {
> +  if (valobj_sp)
> +    return new VariantFrontEnd(*valobj_sp);
> +  return nullptr;
> +}
>
> Added: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.h?rev=342421&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.h (added)
> +++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVariant.h Mon Sep 17 15:10:44 2018
> @@ -0,0 +1,31 @@
> +//===-- LibCxxVariant.h -------------------------------------------*- C++
> +//-*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef liblldb_LibCxxVariant_h_
> +#define liblldb_LibCxxVariant_h_
> +
> +#include "lldb/Core/ValueObject.h"
> +#include "lldb/DataFormatters/TypeSummary.h"
> +#include "lldb/DataFormatters/TypeSynthetic.h"
> +#include "lldb/Utility/Stream.h"
> +
> +namespace lldb_private {
> +namespace formatters {
> +bool LibcxxVariantSummaryProvider(
> +    ValueObject &valobj, Stream &stream,
> +    const TypeSummaryOptions &options); // libc++ std::variant<>
> +
> +SyntheticChildrenFrontEnd *LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
> +                                                        lldb::ValueObjectSP);
> +
> +} // namespace formatters
> +} // namespace lldb_private
> +
> +#endif // liblldb_LibCxxVariant_h_
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


More information about the lldb-commits mailing list