@@ -330,40 +330,135 @@ Interpreter::Visit(const ArraySubscriptNode *node) {
330330 return lhs_or_err;
331331 lldb::ValueObjectSP base = *lhs_or_err;
332332
333- // Check to see if 'base' has a synthetic value; if so, try using that.
333+ StreamString var_expr_path_strm;
334334 uint64_t child_idx = node->GetIndex ();
335- if (lldb::ValueObjectSP synthetic = base->GetSyntheticValue ()) {
336- llvm::Expected<uint32_t > num_children =
337- synthetic->GetNumChildren (child_idx + 1 );
338- if (!num_children)
339- return llvm::make_error<DILDiagnosticError>(
340- m_expr, toString (num_children.takeError ()), node->GetLocation ());
341- if (child_idx >= *num_children) {
342- std::string message = llvm::formatv (
343- " array index {0} is not valid for \" ({1}) {2}\" " , child_idx,
335+ lldb::ValueObjectSP child_valobj_sp;
336+
337+ bool is_incomplete_array = false ;
338+ CompilerType base_type = base->GetCompilerType ().GetNonReferenceType ();
339+ base->GetExpressionPath (var_expr_path_strm);
340+
341+ if (base_type.IsPointerType ()) {
342+ bool is_objc_pointer = true ;
343+
344+ if (base->GetCompilerType ().GetMinimumLanguage () != lldb::eLanguageTypeObjC)
345+ is_objc_pointer = false ;
346+ else if (!base->GetCompilerType ().IsPointerType ())
347+ is_objc_pointer = false ;
348+
349+ if (!m_use_synthetic && is_objc_pointer) {
350+ std::string err_msg = llvm::formatv (
351+ " \" ({0}) {1}\" is an Objective-C pointer, and cannot be subscripted" ,
344352 base->GetTypeName ().AsCString (" <invalid type>" ),
345- base-> GetName (). AsCString ());
346- return llvm::make_error<DILDiagnosticError>(m_expr, message ,
353+ var_expr_path_strm. GetData ());
354+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg) ,
347355 node->GetLocation ());
348356 }
349- if (lldb::ValueObjectSP child_valobj_sp =
350- synthetic->GetChildAtIndex (child_idx))
357+ if (is_objc_pointer) {
358+ lldb::ValueObjectSP synthetic = base->GetSyntheticValue ();
359+ if (!synthetic || synthetic == base) {
360+ std::string err_msg =
361+ llvm::formatv (" \" ({0}) {1}\" is not an array type" ,
362+ base->GetTypeName ().AsCString (" <invalid type>" ),
363+ var_expr_path_strm.GetData ());
364+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
365+ node->GetLocation ());
366+ }
367+ if (static_cast <uint32_t >(child_idx) >=
368+ synthetic->GetNumChildrenIgnoringErrors ()) {
369+ std::string err_msg = llvm::formatv (
370+ " array index {0} is not valid for \" ({1}) {2}\" " , child_idx,
371+ base->GetTypeName ().AsCString (" <invalid type>" ),
372+ var_expr_path_strm.GetData ());
373+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
374+ node->GetLocation ());
375+ }
376+ child_valobj_sp = synthetic->GetChildAtIndex (child_idx);
377+ if (!child_valobj_sp) {
378+ std::string err_msg = llvm::formatv (
379+ " array index {0} is not valid for \" ({1}) {2}\" " , child_idx,
380+ base->GetTypeName ().AsCString (" <invalid type>" ),
381+ var_expr_path_strm.GetData ());
382+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
383+ node->GetLocation ());
384+ }
385+ if (m_use_dynamic != lldb::eNoDynamicValues) {
386+ if (auto dynamic_sp = child_valobj_sp->GetDynamicValue (m_use_dynamic))
387+ child_valobj_sp = std::move (dynamic_sp);
388+ }
351389 return child_valobj_sp;
352- }
390+ }
353391
354- auto base_type = base->GetCompilerType ().GetNonReferenceType ();
355- if (!base_type.IsPointerType () && !base_type.IsArrayType ())
356- return llvm::make_error<DILDiagnosticError>(
357- m_expr, " subscripted value is not an array or pointer" ,
358- node->GetLocation ());
359- if (base_type.IsPointerToVoid ())
360- return llvm::make_error<DILDiagnosticError>(
361- m_expr, " subscript of pointer to incomplete type 'void'" ,
362- node->GetLocation ());
392+ child_valobj_sp = base->GetSyntheticArrayMember (child_idx, true );
393+ if (!child_valobj_sp) {
394+ std::string err_msg = llvm::formatv (
395+ " failed to use pointer as array for index {0} for "
396+ " \" ({1}) {2}\" " ,
397+ child_idx, base->GetTypeName ().AsCString (" <invalid type>" ),
398+ var_expr_path_strm.GetData ());
399+ if (base_type.IsPointerToVoid ())
400+ err_msg = " subscript of pointer to incomplete type 'void'" ;
401+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
402+ node->GetLocation ());
403+ }
404+ } else if (base_type.IsArrayType (nullptr , nullptr , &is_incomplete_array)) {
405+ child_valobj_sp = base->GetChildAtIndex (child_idx);
406+ if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
407+ child_valobj_sp = base->GetSyntheticArrayMember (child_idx, true );
408+ if (!child_valobj_sp) {
409+ std::string err_msg = llvm::formatv (
410+ " array index {0} is not valid for \" ({1}) {2}\" " , child_idx,
411+ base->GetTypeName ().AsCString (" <invalid type>" ),
412+ var_expr_path_strm.GetData ());
413+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
414+ node->GetLocation ());
415+ }
416+ } else if (base_type.IsScalarType ()) {
417+ child_valobj_sp =
418+ base->GetSyntheticBitFieldChild (child_idx, child_idx, true );
419+ if (!child_valobj_sp) {
420+ std::string err_msg = llvm::formatv (
421+ " bitfield range {0}-{1} is not valid for \" ({2}) {3}\" " , child_idx,
422+ child_idx, base->GetTypeName ().AsCString (" <invalid type>" ),
423+ var_expr_path_strm.GetData ());
424+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
425+ node->GetLocation (), 1 );
426+ }
427+ } else {
428+ lldb::ValueObjectSP synthetic = base->GetSyntheticValue ();
429+ if (!m_use_synthetic || !synthetic || synthetic == base) {
430+ std::string err_msg =
431+ llvm::formatv (" \" {0}\" is not an array type" ,
432+ base->GetTypeName ().AsCString (" <invalid type>" ));
433+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
434+ node->GetLocation (), 1 );
435+ }
436+ if (static_cast <uint32_t >(child_idx) >=
437+ synthetic->GetNumChildrenIgnoringErrors (child_idx + 1 )) {
438+ std::string err_msg = llvm::formatv (
439+ " array index {0} is not valid for \" ({1}) {2}\" " , child_idx,
440+ base->GetTypeName ().AsCString (" <invalid type>" ),
441+ var_expr_path_strm.GetData ());
442+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
443+ node->GetLocation (), 1 );
444+ }
445+ child_valobj_sp = synthetic->GetChildAtIndex (child_idx);
446+ if (!child_valobj_sp) {
447+ std::string err_msg = llvm::formatv (
448+ " array index {0} is not valid for \" ({1}) {2}\" " , child_idx,
449+ base->GetTypeName ().AsCString (" <invalid type>" ),
450+ var_expr_path_strm.GetData ());
451+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move (err_msg),
452+ node->GetLocation (), 1 );
453+ }
454+ }
363455
364- if (base_type.IsArrayType ()) {
365- if (lldb::ValueObjectSP child_valobj_sp = base->GetChildAtIndex (child_idx))
366- return child_valobj_sp;
456+ if (child_valobj_sp) {
457+ if (m_use_dynamic != lldb::eNoDynamicValues) {
458+ if (auto dynamic_sp = child_valobj_sp->GetDynamicValue (m_use_dynamic))
459+ child_valobj_sp = std::move (dynamic_sp);
460+ }
461+ return child_valobj_sp;
367462 }
368463
369464 int64_t signed_child_idx = node->GetIndex ();
0 commit comments