@@ -2202,6 +2202,45 @@ void ValueObject::GetExpressionPath(Stream &s,
2202
2202
}
2203
2203
}
2204
2204
2205
+ // Return the alternate value (synthetic if the input object is non-synthetic
2206
+ // and otherwise) this is permitted by the expression path options.
2207
+ static ValueObjectSP GetAlternateValue (
2208
+ ValueObject &valobj,
2209
+ ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal
2210
+ synth_traversal) {
2211
+ using SynthTraversal =
2212
+ ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal;
2213
+
2214
+ if (valobj.IsSynthetic ()) {
2215
+ if (synth_traversal == SynthTraversal::FromSynthetic ||
2216
+ synth_traversal == SynthTraversal::Both)
2217
+ return valobj.GetNonSyntheticValue ();
2218
+ } else {
2219
+ if (synth_traversal == SynthTraversal::ToSynthetic ||
2220
+ synth_traversal == SynthTraversal::Both)
2221
+ return valobj.GetSyntheticValue ();
2222
+ }
2223
+ return nullptr ;
2224
+ }
2225
+
2226
+ // Dereference the provided object or the alternate value, ir permitted by the
2227
+ // expression path options.
2228
+ static ValueObjectSP DereferenceValueOrAlternate (
2229
+ ValueObject &valobj,
2230
+ ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal
2231
+ synth_traversal,
2232
+ Status &error) {
2233
+ error.Clear ();
2234
+ ValueObjectSP result = valobj.Dereference (error);
2235
+ if (!result || error.Fail ()) {
2236
+ if (ValueObjectSP alt_obj = GetAlternateValue (valobj, synth_traversal)) {
2237
+ error.Clear ();
2238
+ result = alt_obj->Dereference (error);
2239
+ }
2240
+ }
2241
+ return result;
2242
+ }
2243
+
2205
2244
ValueObjectSP ValueObject::GetValueForExpressionPath (
2206
2245
llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
2207
2246
ExpressionPathEndResultType *final_value_type,
@@ -2234,7 +2273,8 @@ ValueObjectSP ValueObject::GetValueForExpressionPath(
2234
2273
: dummy_final_task_on_target) ==
2235
2274
ValueObject::eExpressionPathAftermathDereference) {
2236
2275
Status error;
2237
- ValueObjectSP final_value = ret_val->Dereference (error);
2276
+ ValueObjectSP final_value = DereferenceValueOrAlternate (
2277
+ *ret_val, options.m_synthetic_children_traversal , error);
2238
2278
if (error.Fail () || !final_value.get ()) {
2239
2279
if (reason_to_stop)
2240
2280
*reason_to_stop =
@@ -2348,144 +2388,45 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
2348
2388
temp_expression = temp_expression.drop_front (); // skip . or >
2349
2389
2350
2390
size_t next_sep_pos = temp_expression.find_first_of (" -.[" , 1 );
2351
- if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2352
- // expand this last layer
2353
- {
2391
+ if (next_sep_pos == llvm::StringRef::npos) {
2392
+ // if no other separator just expand this last layer
2354
2393
llvm::StringRef child_name = temp_expression;
2355
2394
ValueObjectSP child_valobj_sp =
2356
2395
root->GetChildMemberWithName (child_name);
2357
-
2358
- if (child_valobj_sp.get ()) // we know we are done, so just return
2359
- {
2360
- *reason_to_stop =
2361
- ValueObject::eExpressionPathScanEndReasonEndOfString;
2362
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2363
- return child_valobj_sp;
2364
- } else {
2365
- switch (options.m_synthetic_children_traversal ) {
2366
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2367
- None:
2368
- break ;
2369
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2370
- FromSynthetic:
2371
- if (root->IsSynthetic ()) {
2372
- child_valobj_sp = root->GetNonSyntheticValue ();
2373
- if (child_valobj_sp.get ())
2374
- child_valobj_sp =
2375
- child_valobj_sp->GetChildMemberWithName (child_name);
2376
- }
2377
- break ;
2378
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2379
- ToSynthetic:
2380
- if (!root->IsSynthetic ()) {
2381
- child_valobj_sp = root->GetSyntheticValue ();
2382
- if (child_valobj_sp.get ())
2383
- child_valobj_sp =
2384
- child_valobj_sp->GetChildMemberWithName (child_name);
2385
- }
2386
- break ;
2387
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2388
- Both:
2389
- if (root->IsSynthetic ()) {
2390
- child_valobj_sp = root->GetNonSyntheticValue ();
2391
- if (child_valobj_sp.get ())
2392
- child_valobj_sp =
2393
- child_valobj_sp->GetChildMemberWithName (child_name);
2394
- } else {
2395
- child_valobj_sp = root->GetSyntheticValue ();
2396
- if (child_valobj_sp.get ())
2397
- child_valobj_sp =
2398
- child_valobj_sp->GetChildMemberWithName (child_name);
2399
- }
2400
- break ;
2401
- }
2396
+ if (!child_valobj_sp) {
2397
+ if (ValueObjectSP altroot = GetAlternateValue (
2398
+ *root, options.m_synthetic_children_traversal ))
2399
+ child_valobj_sp = altroot->GetChildMemberWithName (child_name);
2402
2400
}
2403
-
2404
- // if we are here and options.m_no_synthetic_children is true,
2405
- // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2406
- // branch, and return an error
2407
- if (child_valobj_sp.get ()) // if it worked, just return
2408
- {
2401
+ if (child_valobj_sp) {
2409
2402
*reason_to_stop =
2410
2403
ValueObject::eExpressionPathScanEndReasonEndOfString;
2411
2404
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2412
2405
return child_valobj_sp;
2413
- } else {
2414
- *reason_to_stop =
2415
- ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2416
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2417
- return nullptr ;
2418
2406
}
2419
- } else // other layers do expand
2420
- {
2421
- llvm::StringRef next_separator = temp_expression. substr (next_sep_pos) ;
2422
- llvm::StringRef child_name = temp_expression. slice ( 0 , next_sep_pos);
2407
+ *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2408
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2409
+ return nullptr ;
2410
+ }
2423
2411
2424
- ValueObjectSP child_valobj_sp =
2425
- root->GetChildMemberWithName (child_name);
2426
- if (child_valobj_sp.get ()) // store the new root and move on
2427
- {
2428
- root = child_valobj_sp;
2429
- remainder = next_separator;
2430
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2431
- continue ;
2432
- } else {
2433
- switch (options.m_synthetic_children_traversal ) {
2434
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2435
- None:
2436
- break ;
2437
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2438
- FromSynthetic:
2439
- if (root->IsSynthetic ()) {
2440
- child_valobj_sp = root->GetNonSyntheticValue ();
2441
- if (child_valobj_sp.get ())
2442
- child_valobj_sp =
2443
- child_valobj_sp->GetChildMemberWithName (child_name);
2444
- }
2445
- break ;
2446
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2447
- ToSynthetic:
2448
- if (!root->IsSynthetic ()) {
2449
- child_valobj_sp = root->GetSyntheticValue ();
2450
- if (child_valobj_sp.get ())
2451
- child_valobj_sp =
2452
- child_valobj_sp->GetChildMemberWithName (child_name);
2453
- }
2454
- break ;
2455
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2456
- Both:
2457
- if (root->IsSynthetic ()) {
2458
- child_valobj_sp = root->GetNonSyntheticValue ();
2459
- if (child_valobj_sp.get ())
2460
- child_valobj_sp =
2461
- child_valobj_sp->GetChildMemberWithName (child_name);
2462
- } else {
2463
- child_valobj_sp = root->GetSyntheticValue ();
2464
- if (child_valobj_sp.get ())
2465
- child_valobj_sp =
2466
- child_valobj_sp->GetChildMemberWithName (child_name);
2467
- }
2468
- break ;
2469
- }
2470
- }
2412
+ llvm::StringRef next_separator = temp_expression.substr (next_sep_pos);
2413
+ llvm::StringRef child_name = temp_expression.slice (0 , next_sep_pos);
2471
2414
2472
- // if we are here and options.m_no_synthetic_children is true,
2473
- // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2474
- // branch, and return an error
2475
- if (child_valobj_sp.get ()) // if it worked, move on
2476
- {
2477
- root = child_valobj_sp;
2478
- remainder = next_separator;
2479
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2480
- continue ;
2481
- } else {
2482
- *reason_to_stop =
2483
- ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2484
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2485
- return nullptr ;
2486
- }
2415
+ ValueObjectSP child_valobj_sp = root->GetChildMemberWithName (child_name);
2416
+ if (!child_valobj_sp) {
2417
+ if (ValueObjectSP altroot = GetAlternateValue (
2418
+ *root, options.m_synthetic_children_traversal ))
2419
+ child_valobj_sp = altroot->GetChildMemberWithName (child_name);
2487
2420
}
2488
- break ;
2421
+ if (child_valobj_sp) {
2422
+ root = child_valobj_sp;
2423
+ remainder = next_separator;
2424
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2425
+ continue ;
2426
+ }
2427
+ *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2428
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2429
+ return nullptr ;
2489
2430
}
2490
2431
case ' [' : {
2491
2432
if (!root_compiler_type_info.Test (eTypeIsArray) &&
@@ -2601,7 +2542,8 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
2601
2542
// a bitfield
2602
2543
pointee_compiler_type_info.Test (eTypeIsScalar)) {
2603
2544
Status error;
2604
- root = root->Dereference (error);
2545
+ root = DereferenceValueOrAlternate (
2546
+ *root, options.m_synthetic_children_traversal , error);
2605
2547
if (error.Fail () || !root) {
2606
2548
*reason_to_stop =
2607
2549
ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
@@ -2746,7 +2688,8 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
2746
2688
ValueObject::eExpressionPathAftermathDereference &&
2747
2689
pointee_compiler_type_info.Test (eTypeIsScalar)) {
2748
2690
Status error;
2749
- root = root->Dereference (error);
2691
+ root = DereferenceValueOrAlternate (
2692
+ *root, options.m_synthetic_children_traversal , error);
2750
2693
if (error.Fail () || !root) {
2751
2694
*reason_to_stop =
2752
2695
ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
@@ -2916,9 +2859,6 @@ ValueObjectSP ValueObject::Dereference(Status &error) {
2916
2859
}
2917
2860
}
2918
2861
2919
- } else if (HasSyntheticValue ()) {
2920
- m_deref_valobj =
2921
- GetSyntheticValue ()->GetChildMemberWithName (" $$dereference$$" ).get ();
2922
2862
} else if (IsSynthetic ()) {
2923
2863
m_deref_valobj = GetChildMemberWithName (" $$dereference$$" ).get ();
2924
2864
}
0 commit comments