=?utf-8?q?José?= L. Junior <josejun...@10xengineers.ai>,taalhaataahir0102
 <23100...@lums.edu.pk>,taalhaataahir0102 
<23100...@lums.edu.pk>,taalhaataahir0102
 <23100...@lums.edu.pk>,taalhaataahir0102 <23100...@lums.edu.pk>,
=?utf-8?q?José?= L. Junior <josejun...@10xengineers.ai>,
=?utf-8?q?José?= L. Junior <josejun...@10xengineers.ai>,
=?utf-8?q?José?= L. Junior <josejun...@10xengineers.ai>,
=?utf-8?q?José?= L. Junior <josejun...@10xengineers.ai>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/69...@github.com>


================
@@ -246,8 +246,8 @@ class Address {
   /// \see Address::DumpStyle
   bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
             DumpStyle fallback_style = DumpStyleInvalid,
-            uint32_t addr_byte_size = UINT32_MAX,
-            bool all_ranges = false) const;
+            uint32_t addr_byte_size = UINT32_MAX, bool all_ranges = false,
+            const char *pattern = nullptr) const;
----------------
taalhaataahir0102 wrote:

Hi @DavidSpickett! Sorry for the delay 🙏

`test_func3(strm, std::move(regex2))` works but it gives the following problem. 
When we use `std::move(regex2)` to pass it to `test_func3`, it's essentially 
moved, and after the move, the `regex2` in `LookupSymbolInModule` becomes 
garbage.

So in functions where pattern is moved multiple times like this:

```
static void DumpAddress(ExecutionContextScope *exe_scope,
                        const Address &so_addr, bool verbose, bool all_ranges,
                        Stream &strm, std::optional<llvm::Regex> pattern = 
std::nullopt) {
     ...
     ...
     so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
               Address::DumpStyleInvalid, UINT32_MAX, false, 
std::move(pattern));
     ...
     ...
     if (verbose) {
    strm.EOL();
    so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
                 Address::DumpStyleInvalid, UINT32_MAX, all_ranges, 
std::move(pattern));
  }
     ...
}
```
The second `std::move(pattern)`, does not move the original pattern value but 
some garbage value. The only way is to make a copy of the original pattern and 
then use it with `std::move(copy_pattern)` every time (which doesn't look okay 
:-/).

This is the example code and output if I couldn't explain it properly above:
CODE:
```
static void test_func3(Stream &strm, const std::optional<llvm::Regex> pattern = 
std::nullopt) {
  if (pattern.has_value() && pattern.value().match("main")) {
        strm.Printf("Pattern matches 'main' inside test_func3\n");
    }
}

static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
                                     Stream &strm, Module *module,
                                     const char *name, bool name_is_regex,
                                     bool verbose, bool all_ranges) {
  // test_func1(strm, std::make_optional<llvm::Regex>(name));
  std::optional<llvm::Regex> regex2 = std::make_optional<llvm::Regex>(name);
  if (regex2.has_value()) {
    strm.Printf("Pattern has a value\n");
    if(regex2.value().match("main")) {
      strm.Printf("Pattern matches main\n");
    }
    else{
      strm.Printf("Pattern doesn't match main\n");
    }
  } else {
    strm.Printf("Pattern doesn't have a value\n");
  }
  test_func3(strm, std::move(regex2));
  if (regex2.has_value()) {
    strm.Printf("Pattern has a value\n");
    if(regex2.value().match("main")) {
      strm.Printf("Pattern matches main\n");
    }
    else{
      strm.Printf("Pattern doesn't match main\n");
    }
  } else {
    strm.Printf("Pattern doesn't have a value\n");
  }  ...
  ...
}
```
OUTPUT:
```
talha@talha-ROG-Strix-G513QE-G513QE:~/Desktop/LLDB/build/bin$ ./lldb a.out 
(lldb) target create "a.out"
Current executable set to '/home/talha/Desktop/LLDB/build/bin/a.out' (x86_64).
(lldb) image lookup -r -s main
Pattern has a value
Pattern matches main
Pattern matches 'main' inside test_func3
Pattern has a value
Pattern doesn't match main
...
...
```
So after `std::move(pattern)`, `pattern != "main"` within the same function 

Similarly passing `std::make_optional<llvm::Regex>(name)` to func3 also causes 
problem problem:
i.e., `test_func3(strm, std::make_optional<llvm::Regex>(name));`

When we directly pass `std::make_optional<llvm::Regex>(name)`, it creates a 
temporary `std::optional<llvm::Regex>` object that is passed directly to 
`test_func3`. This temporary object can be moved without requiring an explicit 
`std::move` because I guess temporaries are considered rvalues, and 
`std::optional` has appropriate move constructors to handle them.
But storing the result of `std::make_optional<llvm::Regex>(name)` in a variable 
and then passing it without using `std::move`, if the variable is passed as an 
argument to the function, it attempts to perform a copy unless we use 
`std::move`. So, initially we can pass it directly to the next dumping function 
but further passing it will require `std::move` and the same problem comes 
back. 

Also 1 last thing for clarification, as discussed later i.e., 

> I think we may be able to reduce the boilerplate by putting the 
> prefix/suffix/pattern in a struct, and passing that as an optional assuming 
> we can figure out the move issue with regex. But this is for a future change 
> if at all.

The struct will be optional and not the member variables inside it as we can 
check them in the very first function right? 
So the struct will look like:
```
struct information {
pattern, prefix, sufix
}
```
And information will be passed as optional argument rather than
```
struct information {
optional pattern = EMPTY, optional prefix= EMPTY, optional sufix = EMPTY
}
```

https://github.com/llvm/llvm-project/pull/69422
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to