@@ -323,47 +323,144 @@ Interpreter::Visit(const MemberOfNode *node) {
323323 m_expr, errMsg, node->GetLocation (), node->GetFieldName ().size ());
324324}
325325
326+
326327llvm::Expected<lldb::ValueObjectSP>
327328Interpreter::Visit (const ArraySubscriptNode *node) {
328329 auto lhs_or_err = Evaluate (node->GetBase ());
329330 if (!lhs_or_err)
330331 return lhs_or_err;
331332 lldb::ValueObjectSP base = *lhs_or_err;
332333
333- // Check to see if 'base' has a synthetic value; if so, try using that.
334+ StreamString var_expr_path_strm;
334335 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,
344- base->GetTypeName ().AsCString (" <invalid type>" ),
345- base->GetName ().AsCString ());
346- return llvm::make_error<DILDiagnosticError>(m_expr, message,
336+ lldb::ValueObjectSP child_valobj_sp;
337+ bool is_incomplete_array = false ;
338+ CompilerType base_type = base->GetCompilerType ().GetNonReferenceType ();
339+ base->GetExpressionPath (var_expr_path_strm);
340+ if (base_type.IsPointerType ()) {
341+ bool is_objc_pointer = true ;
342+ if (base->GetCompilerType ().GetMinimumLanguage () != lldb::eLanguageTypeObjC)
343+ is_objc_pointer = false ;
344+ else if (!base_type.IsPointerType ())
345+ is_objc_pointer = false ;
346+
347+ if (is_objc_pointer && !m_use_synthetic) {
348+ std::string errMsg =
349+ llvm::formatv (" \" (({0}) {1}\" is an Objective-C pointer, and cannot "
350+ " be subscripted" ,
351+ base->GetTypeName ().AsCString (" <invalid type>" ),
352+ base->GetName ());
353+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
354+ node->GetLocation ());
355+ } else if (is_objc_pointer) {
356+ lldb::ValueObjectSP synthetic = base->GetSyntheticValue ();
357+ if (!synthetic || synthetic == base) {
358+ std::string errMsg =
359+ llvm::formatv (" \" ({0}) {1}\" is not an array type" ,
360+ base->GetTypeName ().AsCString (" <invalid type>" ),
361+ base->GetName ());
362+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
363+ node->GetLocation ());
364+ } else if (static_cast <uint32_t >(child_idx) >=
365+ synthetic->GetNumChildrenIgnoringErrors ()) {
366+ std::string errMsg =
367+ llvm::formatv (" array index {0} is not valid for \" ({1}) {2}\" " ,
368+ child_idx,
369+ base->GetTypeName ().AsCString (" <invalid type>" ),
370+ var_expr_path_strm.GetData ());
371+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
372+ node->GetLocation ());
373+ } else {
374+ child_valobj_sp = synthetic->GetChildAtIndex (child_idx);
375+ if (!child_valobj_sp) {
376+ std::string errMsg =
377+ llvm::formatv (" array index {0} is not valid for \" ({1}) {2}\" " ,
378+ child_idx,
379+ base->GetTypeName ().AsCString (" <invalid type>" ),
380+ var_expr_path_strm.GetData ());
381+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
382+ node->GetLocation ());
383+ }
384+ }
385+ } else { // it's not an objc pointer
386+ child_valobj_sp = base->GetSyntheticArrayMember (child_idx, true );
387+ if (!child_valobj_sp) {
388+ std::string errMsg =
389+ llvm::formatv (" failed to use pointer as array for index {0} for "
390+ " \" ({1}) {2}\" " , child_idx,
391+ base->GetTypeName ().AsCString (" <invalid type>" ),
392+ var_expr_path_strm.GetData ());
393+ if (base_type.IsPointerToVoid ())
394+ errMsg = " subscript of pointer to incomplete type 'void'" ;
395+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
396+ node->GetLocation ());
397+ }
398+ }
399+ } else if (base_type.IsArrayType (
400+ nullptr , nullptr , &is_incomplete_array)) {
401+ child_valobj_sp = base->GetChildAtIndex (child_idx);
402+ if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
403+ child_valobj_sp = base->GetSyntheticArrayMember (child_idx, true );
404+ if (!child_valobj_sp) {
405+ std::string errMsg =
406+ llvm::formatv (" array index {0} is not valid for \" ({1}) {2}\" " ,
407+ child_idx,
408+ base->GetTypeName ().AsCString (" <invalid type>" ),
409+ var_expr_path_strm.GetData ());
410+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
347411 node->GetLocation ());
348412 }
349- if (lldb::ValueObjectSP child_valobj_sp =
350- synthetic->GetChildAtIndex (child_idx))
351- return child_valobj_sp;
413+ } else if (base_type.IsScalarType ()) {
414+ child_valobj_sp =
415+ base->GetSyntheticBitFieldChild (child_idx, child_idx, true );
416+ if (!child_valobj_sp) {
417+ std::string errMsg =
418+ llvm::formatv (" bitfield range {0}-{1} is not valid for \" ({2}) {3}\" " ,
419+ child_idx, child_idx,
420+ base->GetTypeName ().AsCString (" <invalid type>" ),
421+ var_expr_path_strm.GetData ());
422+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
423+ node->GetLocation (), 1 );
424+ }
425+ } else {
426+ lldb::ValueObjectSP synthetic = base->GetSyntheticValue ();
427+ if (!m_use_synthetic || !synthetic || synthetic == base) {
428+ std::string errMsg =
429+ llvm::formatv (" \" {0}\" is not an array type" ,
430+ base->GetTypeName ().AsCString (" <invalid type>" ));
431+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
432+ node->GetLocation (), 1 );
433+ } else if (static_cast <uint32_t >(child_idx) >=
434+ synthetic->GetNumChildrenIgnoringErrors ()) {
435+ std::string errMsg =
436+ llvm::formatv (" array index {0} is not valid for \" ({1}) {2}\" " ,
437+ child_idx,
438+ base->GetTypeName ().AsCString (" <invalid type>" ),
439+ var_expr_path_strm.GetData ());
440+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
441+ node->GetLocation (), 1 );
442+ } else {
443+ child_valobj_sp = synthetic->GetChildAtIndex (child_idx);
444+ if (!child_valobj_sp) {
445+ std::string errMsg =
446+ llvm::formatv (" array index {0} is not valid for \" ({1}) {2}\" " ,
447+ child_idx,
448+ base->GetTypeName ().AsCString (" <invalid type>" ),
449+ var_expr_path_strm.GetData ());
450+ return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
451+ node->GetLocation (), 1 );
452+ }
453+ }
352454 }
353455
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 ());
363-
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+ lldb::ValueObjectSP dynamic_value_sp (
459+ child_valobj_sp->GetDynamicValue (m_use_dynamic));
460+ if (dynamic_value_sp)
461+ child_valobj_sp = dynamic_value_sp;
462+ }
463+ return child_valobj_sp;
367464 }
368465
369466 int64_t signed_child_idx = node->GetIndex ();
0 commit comments