1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917 |
- /* Evaluate expressions for GDB.
- Copyright (C) 1986-2022 Free Software Foundation, Inc.
- This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "defs.h"
- #include "symtab.h"
- #include "gdbtypes.h"
- #include "value.h"
- #include "expression.h"
- #include "target.h"
- #include "frame.h"
- #include "gdbthread.h"
- #include "language.h" /* For CAST_IS_CONVERSION. */
- #include "cp-abi.h"
- #include "infcall.h"
- #include "objc-lang.h"
- #include "block.h"
- #include "parser-defs.h"
- #include "cp-support.h"
- #include "ui-out.h"
- #include "regcache.h"
- #include "user-regs.h"
- #include "valprint.h"
- #include "gdbsupport/gdb_obstack.h"
- #include "objfiles.h"
- #include "typeprint.h"
- #include <ctype.h>
- #include "expop.h"
- #include "c-exp.h"
- #include "inferior.h"
- /* Parse the string EXP as a C expression, evaluate it,
- and return the result as a number. */
- CORE_ADDR
- parse_and_eval_address (const char *exp)
- {
- expression_up expr = parse_expression (exp);
- return value_as_address (evaluate_expression (expr.get ()));
- }
- /* Like parse_and_eval_address, but treats the value of the expression
- as an integer, not an address, returns a LONGEST, not a CORE_ADDR. */
- LONGEST
- parse_and_eval_long (const char *exp)
- {
- expression_up expr = parse_expression (exp);
- return value_as_long (evaluate_expression (expr.get ()));
- }
- struct value *
- parse_and_eval (const char *exp)
- {
- expression_up expr = parse_expression (exp);
- return evaluate_expression (expr.get ());
- }
- /* Parse up to a comma (or to a closeparen)
- in the string EXPP as an expression, evaluate it, and return the value.
- EXPP is advanced to point to the comma. */
- struct value *
- parse_to_comma_and_eval (const char **expp)
- {
- expression_up expr = parse_exp_1 (expp, 0, nullptr, 1);
- return evaluate_expression (expr.get ());
- }
- /* See expression.h. */
- struct value *
- expression::evaluate (struct type *expect_type, enum noside noside)
- {
- gdb::optional<enable_thread_stack_temporaries> stack_temporaries;
- if (target_has_execution () && inferior_ptid != null_ptid
- && language_defn->la_language == language_cplus
- && !thread_stack_temporaries_enabled_p (inferior_thread ()))
- stack_temporaries.emplace (inferior_thread ());
- struct value *retval = op->evaluate (expect_type, this, noside);
- if (stack_temporaries.has_value ()
- && value_in_thread_stack_temporaries (retval, inferior_thread ()))
- retval = value_non_lval (retval);
- return retval;
- }
- /* See value.h. */
- struct value *
- evaluate_expression (struct expression *exp, struct type *expect_type)
- {
- return exp->evaluate (expect_type, EVAL_NORMAL);
- }
- /* Evaluate an expression, avoiding all memory references
- and getting a value whose type alone is correct. */
- struct value *
- evaluate_type (struct expression *exp)
- {
- return exp->evaluate (nullptr, EVAL_AVOID_SIDE_EFFECTS);
- }
- /* Find the current value of a watchpoint on EXP. Return the value in
- *VALP and *RESULTP and the chain of intermediate and final values
- in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does
- not need them.
- If PRESERVE_ERRORS is true, then exceptions are passed through.
- Otherwise, if PRESERVE_ERRORS is false, then if a memory error
- occurs while evaluating the expression, *RESULTP will be set to
- NULL. *RESULTP may be a lazy value, if the result could not be
- read from memory. It is used to determine whether a value is
- user-specified (we should watch the whole value) or intermediate
- (we should watch only the bit used to locate the final value).
- If the final value, or any intermediate value, could not be read
- from memory, *VALP will be set to NULL. *VAL_CHAIN will still be
- set to any referenced values. *VALP will never be a lazy value.
- This is the value which we store in struct breakpoint.
- If VAL_CHAIN is non-NULL, the values put into *VAL_CHAIN will be
- released from the value chain. If VAL_CHAIN is NULL, all generated
- values will be left on the value chain. */
- void
- fetch_subexp_value (struct expression *exp,
- expr::operation *op,
- struct value **valp, struct value **resultp,
- std::vector<value_ref_ptr> *val_chain,
- bool preserve_errors)
- {
- struct value *mark, *new_mark, *result;
- *valp = NULL;
- if (resultp)
- *resultp = NULL;
- if (val_chain)
- val_chain->clear ();
- /* Evaluate the expression. */
- mark = value_mark ();
- result = NULL;
- try
- {
- result = op->evaluate (nullptr, exp, EVAL_NORMAL);
- }
- catch (const gdb_exception &ex)
- {
- /* Ignore memory errors if we want watchpoints pointing at
- inaccessible memory to still be created; otherwise, throw the
- error to some higher catcher. */
- switch (ex.error)
- {
- case MEMORY_ERROR:
- if (!preserve_errors)
- break;
- /* Fall through. */
- default:
- throw;
- break;
- }
- }
- new_mark = value_mark ();
- if (mark == new_mark)
- return;
- if (resultp)
- *resultp = result;
- /* Make sure it's not lazy, so that after the target stops again we
- have a non-lazy previous value to compare with. */
- if (result != NULL)
- {
- if (!value_lazy (result))
- *valp = result;
- else
- {
- try
- {
- value_fetch_lazy (result);
- *valp = result;
- }
- catch (const gdb_exception_error &except)
- {
- }
- }
- }
- if (val_chain)
- {
- /* Return the chain of intermediate values. We use this to
- decide which addresses to watch. */
- *val_chain = value_release_to_mark (mark);
- }
- }
- /* Promote value ARG1 as appropriate before performing a unary operation
- on this argument.
- If the result is not appropriate for any particular language then it
- needs to patch this function. */
- void
- unop_promote (const struct language_defn *language, struct gdbarch *gdbarch,
- struct value **arg1)
- {
- struct type *type1;
- *arg1 = coerce_ref (*arg1);
- type1 = check_typedef (value_type (*arg1));
- if (is_integral_type (type1))
- {
- switch (language->la_language)
- {
- default:
- /* Perform integral promotion for ANSI C/C++.
- If not appropriate for any particular language
- it needs to modify this function. */
- {
- struct type *builtin_int = builtin_type (gdbarch)->builtin_int;
- if (TYPE_LENGTH (type1) < TYPE_LENGTH (builtin_int))
- *arg1 = value_cast (builtin_int, *arg1);
- }
- break;
- }
- }
- }
- /* Promote values ARG1 and ARG2 as appropriate before performing a binary
- operation on those two operands.
- If the result is not appropriate for any particular language then it
- needs to patch this function. */
- void
- binop_promote (const struct language_defn *language, struct gdbarch *gdbarch,
- struct value **arg1, struct value **arg2)
- {
- struct type *promoted_type = NULL;
- struct type *type1;
- struct type *type2;
- *arg1 = coerce_ref (*arg1);
- *arg2 = coerce_ref (*arg2);
- type1 = check_typedef (value_type (*arg1));
- type2 = check_typedef (value_type (*arg2));
- if ((type1->code () != TYPE_CODE_FLT
- && type1->code () != TYPE_CODE_DECFLOAT
- && !is_integral_type (type1))
- || (type2->code () != TYPE_CODE_FLT
- && type2->code () != TYPE_CODE_DECFLOAT
- && !is_integral_type (type2)))
- return;
- if (is_fixed_point_type (type1) || is_fixed_point_type (type2))
- return;
- if (type1->code () == TYPE_CODE_DECFLOAT
- || type2->code () == TYPE_CODE_DECFLOAT)
- {
- /* No promotion required. */
- }
- else if (type1->code () == TYPE_CODE_FLT
- || type2->code () == TYPE_CODE_FLT)
- {
- switch (language->la_language)
- {
- case language_c:
- case language_cplus:
- case language_asm:
- case language_objc:
- case language_opencl:
- /* No promotion required. */
- break;
- default:
- /* For other languages the result type is unchanged from gdb
- version 6.7 for backward compatibility.
- If either arg was long double, make sure that value is also long
- double. Otherwise use double. */
- if (TYPE_LENGTH (type1) * 8 > gdbarch_double_bit (gdbarch)
- || TYPE_LENGTH (type2) * 8 > gdbarch_double_bit (gdbarch))
- promoted_type = builtin_type (gdbarch)->builtin_long_double;
- else
- promoted_type = builtin_type (gdbarch)->builtin_double;
- break;
- }
- }
- else if (type1->code () == TYPE_CODE_BOOL
- && type2->code () == TYPE_CODE_BOOL)
- {
- /* No promotion required. */
- }
- else
- /* Integral operations here. */
- /* FIXME: Also mixed integral/booleans, with result an integer. */
- {
- const struct builtin_type *builtin = builtin_type (gdbarch);
- unsigned int promoted_len1 = TYPE_LENGTH (type1);
- unsigned int promoted_len2 = TYPE_LENGTH (type2);
- int is_unsigned1 = type1->is_unsigned ();
- int is_unsigned2 = type2->is_unsigned ();
- unsigned int result_len;
- int unsigned_operation;
- /* Determine type length and signedness after promotion for
- both operands. */
- if (promoted_len1 < TYPE_LENGTH (builtin->builtin_int))
- {
- is_unsigned1 = 0;
- promoted_len1 = TYPE_LENGTH (builtin->builtin_int);
- }
- if (promoted_len2 < TYPE_LENGTH (builtin->builtin_int))
- {
- is_unsigned2 = 0;
- promoted_len2 = TYPE_LENGTH (builtin->builtin_int);
- }
- if (promoted_len1 > promoted_len2)
- {
- unsigned_operation = is_unsigned1;
- result_len = promoted_len1;
- }
- else if (promoted_len2 > promoted_len1)
- {
- unsigned_operation = is_unsigned2;
- result_len = promoted_len2;
- }
- else
- {
- unsigned_operation = is_unsigned1 || is_unsigned2;
- result_len = promoted_len1;
- }
- switch (language->la_language)
- {
- case language_c:
- case language_cplus:
- case language_asm:
- case language_objc:
- if (result_len <= TYPE_LENGTH (builtin->builtin_int))
- {
- promoted_type = (unsigned_operation
- ? builtin->builtin_unsigned_int
- : builtin->builtin_int);
- }
- else if (result_len <= TYPE_LENGTH (builtin->builtin_long))
- {
- promoted_type = (unsigned_operation
- ? builtin->builtin_unsigned_long
- : builtin->builtin_long);
- }
- else
- {
- promoted_type = (unsigned_operation
- ? builtin->builtin_unsigned_long_long
- : builtin->builtin_long_long);
- }
- break;
- case language_opencl:
- if (result_len <= TYPE_LENGTH (lookup_signed_typename
- (language, "int")))
- {
- promoted_type =
- (unsigned_operation
- ? lookup_unsigned_typename (language, "int")
- : lookup_signed_typename (language, "int"));
- }
- else if (result_len <= TYPE_LENGTH (lookup_signed_typename
- (language, "long")))
- {
- promoted_type =
- (unsigned_operation
- ? lookup_unsigned_typename (language, "long")
- : lookup_signed_typename (language,"long"));
- }
- break;
- default:
- /* For other languages the result type is unchanged from gdb
- version 6.7 for backward compatibility.
- If either arg was long long, make sure that value is also long
- long. Otherwise use long. */
- if (unsigned_operation)
- {
- if (result_len > gdbarch_long_bit (gdbarch) / HOST_CHAR_BIT)
- promoted_type = builtin->builtin_unsigned_long_long;
- else
- promoted_type = builtin->builtin_unsigned_long;
- }
- else
- {
- if (result_len > gdbarch_long_bit (gdbarch) / HOST_CHAR_BIT)
- promoted_type = builtin->builtin_long_long;
- else
- promoted_type = builtin->builtin_long;
- }
- break;
- }
- }
- if (promoted_type)
- {
- /* Promote both operands to common type. */
- *arg1 = value_cast (promoted_type, *arg1);
- *arg2 = value_cast (promoted_type, *arg2);
- }
- }
- static int
- ptrmath_type_p (const struct language_defn *lang, struct type *type)
- {
- type = check_typedef (type);
- if (TYPE_IS_REFERENCE (type))
- type = TYPE_TARGET_TYPE (type);
- switch (type->code ())
- {
- case TYPE_CODE_PTR:
- case TYPE_CODE_FUNC:
- return 1;
- case TYPE_CODE_ARRAY:
- return type->is_vector () ? 0 : lang->c_style_arrays_p ();
- default:
- return 0;
- }
- }
- /* Represents a fake method with the given parameter types. This is
- used by the parser to construct a temporary "expected" type for
- method overload resolution. FLAGS is used as instance flags of the
- new type, in order to be able to make the new type represent a
- const/volatile overload. */
- class fake_method
- {
- public:
- fake_method (type_instance_flags flags,
- int num_types, struct type **param_types);
- ~fake_method ();
- /* The constructed type. */
- struct type *type () { return &m_type; }
- private:
- struct type m_type {};
- main_type m_main_type {};
- };
- fake_method::fake_method (type_instance_flags flags,
- int num_types, struct type **param_types)
- {
- struct type *type = &m_type;
- TYPE_MAIN_TYPE (type) = &m_main_type;
- TYPE_LENGTH (type) = 1;
- type->set_code (TYPE_CODE_METHOD);
- TYPE_CHAIN (type) = type;
- type->set_instance_flags (flags);
- if (num_types > 0)
- {
- if (param_types[num_types - 1] == NULL)
- {
- --num_types;
- type->set_has_varargs (true);
- }
- else if (check_typedef (param_types[num_types - 1])->code ()
- == TYPE_CODE_VOID)
- {
- --num_types;
- /* Caller should have ensured this. */
- gdb_assert (num_types == 0);
- type->set_is_prototyped (true);
- }
- }
- /* We don't use TYPE_ZALLOC here to allocate space as TYPE is owned by
- neither an objfile nor a gdbarch. As a result we must manually
- allocate memory for auxiliary fields, and free the memory ourselves
- when we are done with it. */
- type->set_num_fields (num_types);
- type->set_fields
- ((struct field *) xzalloc (sizeof (struct field) * num_types));
- while (num_types-- > 0)
- type->field (num_types).set_type (param_types[num_types]);
- }
- fake_method::~fake_method ()
- {
- xfree (m_type.fields ());
- }
- namespace expr
- {
- value *
- type_instance_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- type_instance_flags flags = std::get<0> (m_storage);
- std::vector<type *> &types = std::get<1> (m_storage);
- fake_method fake_expect_type (flags, types.size (), types.data ());
- return std::get<2> (m_storage)->evaluate (fake_expect_type.type (),
- exp, noside);
- }
- }
- /* Helper for evaluating an OP_VAR_VALUE. */
- value *
- evaluate_var_value (enum noside noside, const block *blk, symbol *var)
- {
- /* JYG: We used to just return value_zero of the symbol type if
- we're asked to avoid side effects. Otherwise we return
- value_of_variable (...). However I'm not sure if
- value_of_variable () has any side effect. We need a full value
- object returned here for whatis_exp () to call evaluate_type ()
- and then pass the full value to value_rtti_target_type () if we
- are dealing with a pointer or reference to a base class and print
- object is on. */
- struct value *ret = NULL;
- try
- {
- ret = value_of_variable (var, blk);
- }
- catch (const gdb_exception_error &except)
- {
- if (noside != EVAL_AVOID_SIDE_EFFECTS)
- throw;
- ret = value_zero (var->type (), not_lval);
- }
- return ret;
- }
- namespace expr
- {
- value *
- var_value_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- symbol *var = std::get<0> (m_storage).symbol;
- if (var->type ()->code () == TYPE_CODE_ERROR)
- error_unknown_type (var->print_name ());
- return evaluate_var_value (noside, std::get<0> (m_storage).block, var);
- }
- } /* namespace expr */
- /* Helper for evaluating an OP_VAR_MSYM_VALUE. */
- value *
- evaluate_var_msym_value (enum noside noside,
- struct objfile *objfile, minimal_symbol *msymbol)
- {
- CORE_ADDR address;
- type *the_type = find_minsym_type_and_address (msymbol, objfile, &address);
- if (noside == EVAL_AVOID_SIDE_EFFECTS && !the_type->is_gnu_ifunc ())
- return value_zero (the_type, not_lval);
- else
- return value_at_lazy (the_type, address);
- }
- /* See expression.h. */
- value *
- evaluate_subexp_do_call (expression *exp, enum noside noside,
- value *callee,
- gdb::array_view<value *> argvec,
- const char *function_name,
- type *default_return_type)
- {
- if (callee == NULL)
- error (_("Cannot evaluate function -- may be inlined"));
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- /* If the return type doesn't look like a function type,
- call an error. This can happen if somebody tries to turn
- a variable into a function call. */
- type *ftype = value_type (callee);
- if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION)
- {
- /* We don't know anything about what the internal
- function might return, but we have to return
- something. */
- return value_zero (builtin_type (exp->gdbarch)->builtin_int,
- not_lval);
- }
- else if (ftype->code () == TYPE_CODE_XMETHOD)
- {
- type *return_type = result_type_of_xmethod (callee, argvec);
- if (return_type == NULL)
- error (_("Xmethod is missing return type."));
- return value_zero (return_type, not_lval);
- }
- else if (ftype->code () == TYPE_CODE_FUNC
- || ftype->code () == TYPE_CODE_METHOD)
- {
- if (ftype->is_gnu_ifunc ())
- {
- CORE_ADDR address = value_address (callee);
- type *resolved_type = find_gnu_ifunc_target_type (address);
- if (resolved_type != NULL)
- ftype = resolved_type;
- }
- type *return_type = TYPE_TARGET_TYPE (ftype);
- if (return_type == NULL)
- return_type = default_return_type;
- if (return_type == NULL)
- error_call_unknown_return_type (function_name);
- return allocate_value (return_type);
- }
- else
- error (_("Expression of type other than "
- "\"Function returning ...\" used as function"));
- }
- switch (value_type (callee)->code ())
- {
- case TYPE_CODE_INTERNAL_FUNCTION:
- return call_internal_function (exp->gdbarch, exp->language_defn,
- callee, argvec.size (), argvec.data ());
- case TYPE_CODE_XMETHOD:
- return call_xmethod (callee, argvec);
- default:
- return call_function_by_hand (callee, default_return_type, argvec);
- }
- }
- namespace expr
- {
- value *
- operation::evaluate_funcall (struct type *expect_type,
- struct expression *exp,
- enum noside noside,
- const char *function_name,
- const std::vector<operation_up> &args)
- {
- std::vector<value *> vals (args.size ());
- value *callee = evaluate_with_coercion (exp, noside);
- struct type *type = value_type (callee);
- if (type->code () == TYPE_CODE_PTR)
- type = TYPE_TARGET_TYPE (type);
- for (int i = 0; i < args.size (); ++i)
- {
- if (i < type->num_fields ())
- vals[i] = args[i]->evaluate (type->field (i).type (), exp, noside);
- else
- vals[i] = args[i]->evaluate_with_coercion (exp, noside);
- }
- return evaluate_subexp_do_call (exp, noside, callee, vals,
- function_name, expect_type);
- }
- value *
- var_value_operation::evaluate_funcall (struct type *expect_type,
- struct expression *exp,
- enum noside noside,
- const std::vector<operation_up> &args)
- {
- if (!overload_resolution
- || exp->language_defn->la_language != language_cplus)
- return operation::evaluate_funcall (expect_type, exp, noside, args);
- std::vector<value *> argvec (args.size ());
- for (int i = 0; i < args.size (); ++i)
- argvec[i] = args[i]->evaluate_with_coercion (exp, noside);
- struct symbol *symp;
- find_overload_match (argvec, NULL, NON_METHOD,
- NULL, std::get<0> (m_storage).symbol,
- NULL, &symp, NULL, 0, noside);
- if (symp->type ()->code () == TYPE_CODE_ERROR)
- error_unknown_type (symp->print_name ());
- value *callee = evaluate_var_value (noside, std::get<0> (m_storage).block,
- symp);
- return evaluate_subexp_do_call (exp, noside, callee, argvec,
- nullptr, expect_type);
- }
- value *
- scope_operation::evaluate_funcall (struct type *expect_type,
- struct expression *exp,
- enum noside noside,
- const std::vector<operation_up> &args)
- {
- if (!overload_resolution
- || exp->language_defn->la_language != language_cplus)
- return operation::evaluate_funcall (expect_type, exp, noside, args);
- /* Unpack it locally so we can properly handle overload
- resolution. */
- const std::string &name = std::get<1> (m_storage);
- struct type *type = std::get<0> (m_storage);
- symbol *function = NULL;
- const char *function_name = NULL;
- std::vector<value *> argvec (1 + args.size ());
- if (type->code () == TYPE_CODE_NAMESPACE)
- {
- function = cp_lookup_symbol_namespace (type->name (),
- name.c_str (),
- get_selected_block (0),
- VAR_DOMAIN).symbol;
- if (function == NULL)
- error (_("No symbol \"%s\" in namespace \"%s\"."),
- name.c_str (), type->name ());
- }
- else
- {
- gdb_assert (type->code () == TYPE_CODE_STRUCT
- || type->code () == TYPE_CODE_UNION);
- function_name = name.c_str ();
- /* We need a properly typed value for method lookup. */
- argvec[0] = value_zero (type, lval_memory);
- }
- for (int i = 0; i < args.size (); ++i)
- argvec[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
- gdb::array_view<value *> arg_view = argvec;
- value *callee = nullptr;
- if (function_name != nullptr)
- {
- int static_memfuncp;
- find_overload_match (arg_view, function_name, METHOD,
- &argvec[0], nullptr, &callee, nullptr,
- &static_memfuncp, 0, noside);
- if (!static_memfuncp)
- {
- /* For the time being, we don't handle this. */
- error (_("Call to overloaded function %s requires "
- "`this' pointer"),
- function_name);
- }
- arg_view = arg_view.slice (1);
- }
- else
- {
- symbol *symp;
- arg_view = arg_view.slice (1);
- find_overload_match (arg_view, nullptr,
- NON_METHOD, nullptr, function,
- nullptr, &symp, nullptr, 1, noside);
- callee = value_of_variable (symp, get_selected_block (0));
- }
- return evaluate_subexp_do_call (exp, noside, callee, arg_view,
- nullptr, expect_type);
- }
- value *
- structop_member_base::evaluate_funcall (struct type *expect_type,
- struct expression *exp,
- enum noside noside,
- const std::vector<operation_up> &args)
- {
- /* First, evaluate the structure into lhs. */
- value *lhs;
- if (opcode () == STRUCTOP_MEMBER)
- lhs = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
- else
- lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- std::vector<value *> vals (args.size () + 1);
- gdb::array_view<value *> val_view = vals;
- /* If the function is a virtual function, then the aggregate
- value (providing the structure) plays its part by providing
- the vtable. Otherwise, it is just along for the ride: call
- the function directly. */
- value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- value *callee;
- type *a1_type = check_typedef (value_type (rhs));
- if (a1_type->code () == TYPE_CODE_METHODPTR)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- callee = value_zero (TYPE_TARGET_TYPE (a1_type), not_lval);
- else
- callee = cplus_method_ptr_to_value (&lhs, rhs);
- vals[0] = lhs;
- }
- else if (a1_type->code () == TYPE_CODE_MEMBERPTR)
- {
- struct type *type_ptr
- = lookup_pointer_type (TYPE_SELF_TYPE (a1_type));
- struct type *target_type_ptr
- = lookup_pointer_type (TYPE_TARGET_TYPE (a1_type));
- /* Now, convert this value to an address. */
- lhs = value_cast (type_ptr, lhs);
- long mem_offset = value_as_long (rhs);
- callee = value_from_pointer (target_type_ptr,
- value_as_long (lhs) + mem_offset);
- callee = value_ind (callee);
- val_view = val_view.slice (1);
- }
- else
- error (_("Non-pointer-to-member value used in pointer-to-member "
- "construct"));
- for (int i = 0; i < args.size (); ++i)
- vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
- return evaluate_subexp_do_call (exp, noside, callee, val_view,
- nullptr, expect_type);
- }
- value *
- structop_base_operation::evaluate_funcall
- (struct type *expect_type, struct expression *exp, enum noside noside,
- const std::vector<operation_up> &args)
- {
- /* Allocate space for the function call arguments, Including space for a
- `this' pointer at the start. */
- std::vector<value *> vals (args.size () + 1);
- /* First, evaluate the structure into vals[0]. */
- enum exp_opcode op = opcode ();
- if (op == STRUCTOP_STRUCT)
- {
- /* If v is a variable in a register, and the user types
- v.method (), this will produce an error, because v has no
- address.
- A possible way around this would be to allocate a copy of
- the variable on the stack, copy in the contents, call the
- function, and copy out the contents. I.e. convert this
- from call by reference to call by copy-return (or
- whatever it's called). However, this does not work
- because it is not the same: the method being called could
- stash a copy of the address, and then future uses through
- that address (after the method returns) would be expected
- to use the variable itself, not some copy of it. */
- vals[0] = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
- }
- else
- {
- vals[0] = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- /* Check to see if the operator '->' has been overloaded.
- If the operator has been overloaded replace vals[0] with the
- value returned by the custom operator and continue
- evaluation. */
- while (unop_user_defined_p (op, vals[0]))
- {
- struct value *value = nullptr;
- try
- {
- value = value_x_unop (vals[0], op, noside);
- }
- catch (const gdb_exception_error &except)
- {
- if (except.error == NOT_FOUND_ERROR)
- break;
- else
- throw;
- }
- vals[0] = value;
- }
- }
- /* Evaluate the arguments. The '+ 1' here is to allow for the `this'
- pointer we placed into vals[0]. */
- for (int i = 0; i < args.size (); ++i)
- vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
- /* The array view includes the `this' pointer. */
- gdb::array_view<value *> arg_view (vals);
- int static_memfuncp;
- value *callee;
- const char *tstr = std::get<1> (m_storage).c_str ();
- if (overload_resolution
- && exp->language_defn->la_language == language_cplus)
- {
- /* Language is C++, do some overload resolution before
- evaluation. */
- value *val0 = vals[0];
- find_overload_match (arg_view, tstr, METHOD,
- &val0, nullptr, &callee, nullptr,
- &static_memfuncp, 0, noside);
- vals[0] = val0;
- }
- else
- /* Non-C++ case -- or no overload resolution. */
- {
- struct value *temp = vals[0];
- callee = value_struct_elt (&temp, arg_view, tstr,
- &static_memfuncp,
- op == STRUCTOP_STRUCT
- ? "structure" : "structure pointer");
- /* value_struct_elt updates temp with the correct value of the
- ``this'' pointer if necessary, so modify it to reflect any
- ``this'' changes. */
- vals[0] = value_from_longest (lookup_pointer_type (value_type (temp)),
- value_address (temp)
- + value_embedded_offset (temp));
- }
- /* Take out `this' if needed. */
- if (static_memfuncp)
- arg_view = arg_view.slice (1);
- return evaluate_subexp_do_call (exp, noside, callee, arg_view,
- nullptr, expect_type);
- }
- /* Helper for structop_base_operation::complete which recursively adds
- field and method names from TYPE, a struct or union type, to the
- OUTPUT list. PREFIX is prepended to each result. */
- static void
- add_struct_fields (struct type *type, completion_list &output,
- const char *fieldname, int namelen, const char *prefix)
- {
- int i;
- int computed_type_name = 0;
- const char *type_name = NULL;
- type = check_typedef (type);
- for (i = 0; i < type->num_fields (); ++i)
- {
- if (i < TYPE_N_BASECLASSES (type))
- add_struct_fields (TYPE_BASECLASS (type, i),
- output, fieldname, namelen, prefix);
- else if (type->field (i).name ())
- {
- if (type->field (i).name ()[0] != '\0')
- {
- if (! strncmp (type->field (i).name (),
- fieldname, namelen))
- output.emplace_back (concat (prefix, type->field (i).name (),
- nullptr));
- }
- else if (type->field (i).type ()->code () == TYPE_CODE_UNION)
- {
- /* Recurse into anonymous unions. */
- add_struct_fields (type->field (i).type (),
- output, fieldname, namelen, prefix);
- }
- }
- }
- for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
- {
- const char *name = TYPE_FN_FIELDLIST_NAME (type, i);
- if (name && ! strncmp (name, fieldname, namelen))
- {
- if (!computed_type_name)
- {
- type_name = type->name ();
- computed_type_name = 1;
- }
- /* Omit constructors from the completion list. */
- if (!type_name || strcmp (type_name, name))
- output.emplace_back (concat (prefix, name, nullptr));
- }
- }
- }
- /* See expop.h. */
- bool
- structop_base_operation::complete (struct expression *exp,
- completion_tracker &tracker,
- const char *prefix)
- {
- const std::string &fieldname = std::get<1> (m_storage);
- value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp,
- EVAL_AVOID_SIDE_EFFECTS);
- struct type *type = value_type (lhs);
- for (;;)
- {
- type = check_typedef (type);
- if (!type->is_pointer_or_reference ())
- break;
- type = TYPE_TARGET_TYPE (type);
- }
- if (type->code () == TYPE_CODE_UNION
- || type->code () == TYPE_CODE_STRUCT)
- {
- completion_list result;
- add_struct_fields (type, result, fieldname.c_str (),
- fieldname.length (), prefix);
- tracker.add_completions (std::move (result));
- return true;
- }
- return false;
- }
- } /* namespace expr */
- /* Return true if type is integral or reference to integral */
- static bool
- is_integral_or_integral_reference (struct type *type)
- {
- if (is_integral_type (type))
- return true;
- type = check_typedef (type);
- return (type != nullptr
- && TYPE_IS_REFERENCE (type)
- && is_integral_type (TYPE_TARGET_TYPE (type)));
- }
- /* Helper function that implements the body of OP_SCOPE. */
- struct value *
- eval_op_scope (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct type *type, const char *string)
- {
- struct value *arg1 = value_aggregate_elt (type, string, expect_type,
- 0, noside);
- if (arg1 == NULL)
- error (_("There is no field named %s"), string);
- return arg1;
- }
- /* Helper function that implements the body of OP_VAR_ENTRY_VALUE. */
- struct value *
- eval_op_var_entry_value (struct type *expect_type, struct expression *exp,
- enum noside noside, symbol *sym)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (sym->type (), not_lval);
- if (SYMBOL_COMPUTED_OPS (sym) == NULL
- || SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry == NULL)
- error (_("Symbol \"%s\" does not have any specific entry value"),
- sym->print_name ());
- struct frame_info *frame = get_selected_frame (NULL);
- return SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry (sym, frame);
- }
- /* Helper function that implements the body of OP_VAR_MSYM_VALUE. */
- struct value *
- eval_op_var_msym_value (struct type *expect_type, struct expression *exp,
- enum noside noside, bool outermost_p,
- bound_minimal_symbol msymbol)
- {
- value *val = evaluate_var_msym_value (noside, msymbol.objfile,
- msymbol.minsym);
- struct type *type = value_type (val);
- if (type->code () == TYPE_CODE_ERROR
- && (noside != EVAL_AVOID_SIDE_EFFECTS || !outermost_p))
- error_unknown_type (msymbol.minsym->print_name ());
- return val;
- }
- /* Helper function that implements the body of OP_FUNC_STATIC_VAR. */
- struct value *
- eval_op_func_static_var (struct type *expect_type, struct expression *exp,
- enum noside noside,
- value *func, const char *var)
- {
- CORE_ADDR addr = value_address (func);
- const block *blk = block_for_pc (addr);
- struct block_symbol sym = lookup_symbol (var, blk, VAR_DOMAIN, NULL);
- if (sym.symbol == NULL)
- error (_("No symbol \"%s\" in specified context."), var);
- return evaluate_var_value (noside, sym.block, sym.symbol);
- }
- /* Helper function that implements the body of OP_REGISTER. */
- struct value *
- eval_op_register (struct type *expect_type, struct expression *exp,
- enum noside noside, const char *name)
- {
- int regno;
- struct value *val;
- regno = user_reg_map_name_to_regnum (exp->gdbarch,
- name, strlen (name));
- if (regno == -1)
- error (_("Register $%s not available."), name);
- /* In EVAL_AVOID_SIDE_EFFECTS mode, we only need to return
- a value with the appropriate register type. Unfortunately,
- we don't have easy access to the type of user registers.
- So for these registers, we fetch the register value regardless
- of the evaluation mode. */
- if (noside == EVAL_AVOID_SIDE_EFFECTS
- && regno < gdbarch_num_cooked_regs (exp->gdbarch))
- val = value_zero (register_type (exp->gdbarch, regno), not_lval);
- else
- val = value_of_register (regno, get_selected_frame (NULL));
- if (val == NULL)
- error (_("Value of register %s not available."), name);
- else
- return val;
- }
- namespace expr
- {
- value *
- string_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- const std::string &str = std::get<0> (m_storage);
- struct type *type = language_string_char_type (exp->language_defn,
- exp->gdbarch);
- return value_string (str.c_str (), str.size (), type);
- }
- } /* namespace expr */
- /* Helper function that implements the body of OP_OBJC_SELECTOR. */
- struct value *
- eval_op_objc_selector (struct type *expect_type, struct expression *exp,
- enum noside noside,
- const char *sel)
- {
- struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
- return value_from_longest (selector_type,
- lookup_child_selector (exp->gdbarch, sel));
- }
- /* A helper function for TERNOP_SLICE. */
- struct value *
- eval_op_ternop (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *array, struct value *low, struct value *upper)
- {
- int lowbound = value_as_long (low);
- int upperbound = value_as_long (upper);
- return value_slice (array, lowbound, upperbound - lowbound + 1);
- }
- /* A helper function for STRUCTOP_STRUCT. */
- struct value *
- eval_op_structop_struct (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1, const char *string)
- {
- struct value *arg3 = value_struct_elt (&arg1, {}, string,
- NULL, "structure");
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- arg3 = value_zero (value_type (arg3), VALUE_LVAL (arg3));
- return arg3;
- }
- /* A helper function for STRUCTOP_PTR. */
- struct value *
- eval_op_structop_ptr (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1, const char *string)
- {
- /* Check to see if operator '->' has been overloaded. If so replace
- arg1 with the value returned by evaluating operator->(). */
- while (unop_user_defined_p (STRUCTOP_PTR, arg1))
- {
- struct value *value = NULL;
- try
- {
- value = value_x_unop (arg1, STRUCTOP_PTR, noside);
- }
- catch (const gdb_exception_error &except)
- {
- if (except.error == NOT_FOUND_ERROR)
- break;
- else
- throw;
- }
- arg1 = value;
- }
- /* JYG: if print object is on we need to replace the base type
- with rtti type in order to continue on with successful
- lookup of member / method only available in the rtti type. */
- {
- struct type *arg_type = value_type (arg1);
- struct type *real_type;
- int full, using_enc;
- LONGEST top;
- struct value_print_options opts;
- get_user_print_options (&opts);
- if (opts.objectprint && TYPE_TARGET_TYPE (arg_type)
- && (TYPE_TARGET_TYPE (arg_type)->code () == TYPE_CODE_STRUCT))
- {
- real_type = value_rtti_indirect_type (arg1, &full, &top,
- &using_enc);
- if (real_type)
- arg1 = value_cast (real_type, arg1);
- }
- }
- struct value *arg3 = value_struct_elt (&arg1, {}, string,
- NULL, "structure pointer");
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- arg3 = value_zero (value_type (arg3), VALUE_LVAL (arg3));
- return arg3;
- }
- /* A helper function for STRUCTOP_MEMBER. */
- struct value *
- eval_op_member (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1, struct value *arg2)
- {
- long mem_offset;
- struct value *arg3;
- struct type *type = check_typedef (value_type (arg2));
- switch (type->code ())
- {
- case TYPE_CODE_METHODPTR:
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (TYPE_TARGET_TYPE (type), not_lval);
- else
- {
- arg2 = cplus_method_ptr_to_value (&arg1, arg2);
- gdb_assert (value_type (arg2)->code () == TYPE_CODE_PTR);
- return value_ind (arg2);
- }
- case TYPE_CODE_MEMBERPTR:
- /* Now, convert these values to an address. */
- arg1 = value_cast_pointers (lookup_pointer_type (TYPE_SELF_TYPE (type)),
- arg1, 1);
- mem_offset = value_as_long (arg2);
- arg3 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
- value_as_long (arg1) + mem_offset);
- return value_ind (arg3);
- default:
- error (_("non-pointer-to-member value used "
- "in pointer-to-member construct"));
- }
- }
- /* A helper function for BINOP_ADD. */
- struct value *
- eval_op_add (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (BINOP_ADD, arg1, arg2))
- return value_x_binop (arg1, arg2, BINOP_ADD, OP_NULL, noside);
- else if (ptrmath_type_p (exp->language_defn, value_type (arg1))
- && is_integral_or_integral_reference (value_type (arg2)))
- return value_ptradd (arg1, value_as_long (arg2));
- else if (ptrmath_type_p (exp->language_defn, value_type (arg2))
- && is_integral_or_integral_reference (value_type (arg1)))
- return value_ptradd (arg2, value_as_long (arg1));
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- return value_binop (arg1, arg2, BINOP_ADD);
- }
- }
- /* A helper function for BINOP_SUB. */
- struct value *
- eval_op_sub (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (BINOP_SUB, arg1, arg2))
- return value_x_binop (arg1, arg2, BINOP_SUB, OP_NULL, noside);
- else if (ptrmath_type_p (exp->language_defn, value_type (arg1))
- && ptrmath_type_p (exp->language_defn, value_type (arg2)))
- {
- /* FIXME -- should be ptrdiff_t */
- struct type *type = builtin_type (exp->gdbarch)->builtin_long;
- return value_from_longest (type, value_ptrdiff (arg1, arg2));
- }
- else if (ptrmath_type_p (exp->language_defn, value_type (arg1))
- && is_integral_or_integral_reference (value_type (arg2)))
- return value_ptradd (arg1, - value_as_long (arg2));
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- return value_binop (arg1, arg2, BINOP_SUB);
- }
- }
- /* Helper function for several different binary operations. */
- struct value *
- eval_op_binary (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- else
- {
- /* If EVAL_AVOID_SIDE_EFFECTS and we're dividing by zero,
- fudge arg2 to avoid division-by-zero, the caller is
- (theoretically) only looking for the type of the result. */
- if (noside == EVAL_AVOID_SIDE_EFFECTS
- /* ??? Do we really want to test for BINOP_MOD here?
- The implementation of value_binop gives it a well-defined
- value. */
- && (op == BINOP_DIV
- || op == BINOP_INTDIV
- || op == BINOP_REM
- || op == BINOP_MOD)
- && value_logical_not (arg2))
- {
- struct value *v_one;
- v_one = value_one (value_type (arg2));
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &v_one);
- return value_binop (arg1, v_one, op);
- }
- else
- {
- /* For shift and integer exponentiation operations,
- only promote the first argument. */
- if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP)
- && is_integral_type (value_type (arg2)))
- unop_promote (exp->language_defn, exp->gdbarch, &arg1);
- else
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- return value_binop (arg1, arg2, op);
- }
- }
- }
- /* A helper function for BINOP_SUBSCRIPT. */
- struct value *
- eval_op_subscript (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- else
- {
- /* If the user attempts to subscript something that is not an
- array or pointer type (like a plain int variable for example),
- then report this as an error. */
- arg1 = coerce_ref (arg1);
- struct type *type = check_typedef (value_type (arg1));
- if (type->code () != TYPE_CODE_ARRAY
- && type->code () != TYPE_CODE_PTR)
- {
- if (type->name ())
- error (_("cannot subscript something of type `%s'"),
- type->name ());
- else
- error (_("cannot subscript requested type"));
- }
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
- else
- return value_subscript (arg1, value_as_long (arg2));
- }
- }
- /* A helper function for BINOP_EQUAL. */
- struct value *
- eval_op_equal (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- }
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- int tem = value_equal (arg1, arg2);
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, (LONGEST) tem);
- }
- }
- /* A helper function for BINOP_NOTEQUAL. */
- struct value *
- eval_op_notequal (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- }
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- int tem = value_equal (arg1, arg2);
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, (LONGEST) ! tem);
- }
- }
- /* A helper function for BINOP_LESS. */
- struct value *
- eval_op_less (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- }
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- int tem = value_less (arg1, arg2);
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, (LONGEST) tem);
- }
- }
- /* A helper function for BINOP_GTR. */
- struct value *
- eval_op_gtr (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- }
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- int tem = value_less (arg2, arg1);
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, (LONGEST) tem);
- }
- }
- /* A helper function for BINOP_GEQ. */
- struct value *
- eval_op_geq (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- }
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- int tem = value_less (arg2, arg1) || value_equal (arg1, arg2);
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, (LONGEST) tem);
- }
- }
- /* A helper function for BINOP_LEQ. */
- struct value *
- eval_op_leq (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, OP_NULL, noside);
- }
- else
- {
- binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
- int tem = value_less (arg1, arg2) || value_equal (arg1, arg2);
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, (LONGEST) tem);
- }
- }
- /* A helper function for BINOP_REPEAT. */
- struct value *
- eval_op_repeat (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- struct type *type = check_typedef (value_type (arg2));
- if (type->code () != TYPE_CODE_INT
- && type->code () != TYPE_CODE_ENUM)
- error (_("Non-integral right operand for \"@\" operator."));
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- return allocate_repeat_value (value_type (arg1),
- longest_to_int (value_as_long (arg2)));
- }
- else
- return value_repeat (arg1, longest_to_int (value_as_long (arg2)));
- }
- /* A helper function for UNOP_PLUS. */
- struct value *
- eval_op_plus (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op, noside);
- else
- {
- unop_promote (exp->language_defn, exp->gdbarch, &arg1);
- return value_pos (arg1);
- }
- }
- /* A helper function for UNOP_NEG. */
- struct value *
- eval_op_neg (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op, noside);
- else
- {
- unop_promote (exp->language_defn, exp->gdbarch, &arg1);
- return value_neg (arg1);
- }
- }
- /* A helper function for UNOP_COMPLEMENT. */
- struct value *
- eval_op_complement (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (unop_user_defined_p (UNOP_COMPLEMENT, arg1))
- return value_x_unop (arg1, UNOP_COMPLEMENT, noside);
- else
- {
- unop_promote (exp->language_defn, exp->gdbarch, &arg1);
- return value_complement (arg1);
- }
- }
- /* A helper function for UNOP_LOGICAL_NOT. */
- struct value *
- eval_op_lognot (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op, noside);
- else
- {
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, (LONGEST) value_logical_not (arg1));
- }
- }
- /* A helper function for UNOP_IND. */
- struct value *
- eval_op_ind (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1)
- {
- struct type *type = check_typedef (value_type (arg1));
- if (type->code () == TYPE_CODE_METHODPTR
- || type->code () == TYPE_CODE_MEMBERPTR)
- error (_("Attempt to dereference pointer "
- "to member without an object"));
- if (unop_user_defined_p (UNOP_IND, arg1))
- return value_x_unop (arg1, UNOP_IND, noside);
- else if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- type = check_typedef (value_type (arg1));
- /* If the type pointed to is dynamic then in order to resolve the
- dynamic properties we must actually dereference the pointer.
- There is a risk that this dereference will have side-effects
- in the inferior, but being able to print accurate type
- information seems worth the risk. */
- if (!type->is_pointer_or_reference ()
- || !is_dynamic_type (TYPE_TARGET_TYPE (type)))
- {
- if (type->is_pointer_or_reference ()
- /* In C you can dereference an array to get the 1st elt. */
- || type->code () == TYPE_CODE_ARRAY)
- return value_zero (TYPE_TARGET_TYPE (type),
- lval_memory);
- else if (type->code () == TYPE_CODE_INT)
- /* GDB allows dereferencing an int. */
- return value_zero (builtin_type (exp->gdbarch)->builtin_int,
- lval_memory);
- else
- error (_("Attempt to take contents of a non-pointer value."));
- }
- }
- /* Allow * on an integer so we can cast it to whatever we want.
- This returns an int, which seems like the most C-like thing to
- do. "long long" variables are rare enough that
- BUILTIN_TYPE_LONGEST would seem to be a mistake. */
- if (type->code () == TYPE_CODE_INT)
- return value_at_lazy (builtin_type (exp->gdbarch)->builtin_int,
- (CORE_ADDR) value_as_address (arg1));
- return value_ind (arg1);
- }
- /* A helper function for UNOP_ALIGNOF. */
- struct value *
- eval_op_alignof (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1)
- {
- struct type *type = value_type (arg1);
- /* FIXME: This should be size_t. */
- struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
- ULONGEST align = type_align (type);
- if (align == 0)
- error (_("could not determine alignment of type"));
- return value_from_longest (size_type, align);
- }
- /* A helper function for UNOP_MEMVAL. */
- struct value *
- eval_op_memval (struct type *expect_type, struct expression *exp,
- enum noside noside,
- struct value *arg1, struct type *type)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (type, lval_memory);
- else
- return value_at_lazy (type, value_as_address (arg1));
- }
- /* A helper function for UNOP_PREINCREMENT. */
- struct value *
- eval_op_preinc (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op, noside);
- }
- else
- {
- struct value *arg2;
- if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
- arg2 = value_ptradd (arg1, 1);
- else
- {
- struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1));
- binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
- arg2 = value_binop (tmp, arg2, BINOP_ADD);
- }
- return value_assign (arg1, arg2);
- }
- }
- /* A helper function for UNOP_PREDECREMENT. */
- struct value *
- eval_op_predec (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op, noside);
- }
- else
- {
- struct value *arg2;
- if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
- arg2 = value_ptradd (arg1, -1);
- else
- {
- struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1));
- binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
- arg2 = value_binop (tmp, arg2, BINOP_SUB);
- }
- return value_assign (arg1, arg2);
- }
- }
- /* A helper function for UNOP_POSTINCREMENT. */
- struct value *
- eval_op_postinc (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op, noside);
- }
- else
- {
- struct value *arg3 = value_non_lval (arg1);
- struct value *arg2;
- if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
- arg2 = value_ptradd (arg1, 1);
- else
- {
- struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1));
- binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
- arg2 = value_binop (tmp, arg2, BINOP_ADD);
- }
- value_assign (arg1, arg2);
- return arg3;
- }
- }
- /* A helper function for UNOP_POSTDECREMENT. */
- struct value *
- eval_op_postdec (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op, noside);
- }
- else
- {
- struct value *arg3 = value_non_lval (arg1);
- struct value *arg2;
- if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
- arg2 = value_ptradd (arg1, -1);
- else
- {
- struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1));
- binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
- arg2 = value_binop (tmp, arg2, BINOP_SUB);
- }
- value_assign (arg1, arg2);
- return arg3;
- }
- }
- /* A helper function for OP_TYPE. */
- struct value *
- eval_op_type (struct type *expect_type, struct expression *exp,
- enum noside noside, struct type *type)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return allocate_value (type);
- else
- error (_("Attempt to use a type name as an expression"));
- }
- /* A helper function for BINOP_ASSIGN_MODIFY. */
- struct value *
- eval_binop_assign_modify (struct type *expect_type, struct expression *exp,
- enum noside noside, enum exp_opcode op,
- struct value *arg1, struct value *arg2)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside);
- else if (op == BINOP_ADD && ptrmath_type_p (exp->language_defn,
- value_type (arg1))
- && is_integral_type (value_type (arg2)))
- arg2 = value_ptradd (arg1, value_as_long (arg2));
- else if (op == BINOP_SUB && ptrmath_type_p (exp->language_defn,
- value_type (arg1))
- && is_integral_type (value_type (arg2)))
- arg2 = value_ptradd (arg1, - value_as_long (arg2));
- else
- {
- struct value *tmp = arg1;
- /* For shift and integer exponentiation operations,
- only promote the first argument. */
- if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP)
- && is_integral_type (value_type (arg2)))
- unop_promote (exp->language_defn, exp->gdbarch, &tmp);
- else
- binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
- arg2 = value_binop (tmp, arg2, op);
- }
- return value_assign (arg1, arg2);
- }
- /* Note that ARGS needs 2 empty slots up front and must end with a
- null pointer. */
- static struct value *
- eval_op_objc_msgcall (struct type *expect_type, struct expression *exp,
- enum noside noside, CORE_ADDR selector,
- value *target, gdb::array_view<value *> args)
- {
- CORE_ADDR responds_selector = 0;
- CORE_ADDR method_selector = 0;
- int struct_return = 0;
- struct value *msg_send = NULL;
- struct value *msg_send_stret = NULL;
- int gnu_runtime = 0;
- struct value *method = NULL;
- struct value *called_method = NULL;
- struct type *selector_type = NULL;
- struct type *long_type;
- struct type *type;
- struct value *ret = NULL;
- CORE_ADDR addr = 0;
- value *argvec[5];
- long_type = builtin_type (exp->gdbarch)->builtin_long;
- selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
- if (value_as_long (target) == 0)
- return value_from_longest (long_type, 0);
- if (lookup_minimal_symbol ("objc_msg_lookup", 0, 0).minsym)
- gnu_runtime = 1;
- /* Find the method dispatch (Apple runtime) or method lookup
- (GNU runtime) function for Objective-C. These will be used
- to lookup the symbol information for the method. If we
- can't find any symbol information, then we'll use these to
- call the method, otherwise we can call the method
- directly. The msg_send_stret function is used in the special
- case of a method that returns a structure (Apple runtime
- only). */
- if (gnu_runtime)
- {
- type = selector_type;
- type = lookup_function_type (type);
- type = lookup_pointer_type (type);
- type = lookup_function_type (type);
- type = lookup_pointer_type (type);
- msg_send = find_function_in_inferior ("objc_msg_lookup", NULL);
- msg_send_stret
- = find_function_in_inferior ("objc_msg_lookup", NULL);
- msg_send = value_from_pointer (type, value_as_address (msg_send));
- msg_send_stret = value_from_pointer (type,
- value_as_address (msg_send_stret));
- }
- else
- {
- msg_send = find_function_in_inferior ("objc_msgSend", NULL);
- /* Special dispatcher for methods returning structs. */
- msg_send_stret
- = find_function_in_inferior ("objc_msgSend_stret", NULL);
- }
- /* Verify the target object responds to this method. The
- standard top-level 'Object' class uses a different name for
- the verification method than the non-standard, but more
- often used, 'NSObject' class. Make sure we check for both. */
- responds_selector
- = lookup_child_selector (exp->gdbarch, "respondsToSelector:");
- if (responds_selector == 0)
- responds_selector
- = lookup_child_selector (exp->gdbarch, "respondsTo:");
- if (responds_selector == 0)
- error (_("no 'respondsTo:' or 'respondsToSelector:' method"));
- method_selector
- = lookup_child_selector (exp->gdbarch, "methodForSelector:");
- if (method_selector == 0)
- method_selector
- = lookup_child_selector (exp->gdbarch, "methodFor:");
- if (method_selector == 0)
- error (_("no 'methodFor:' or 'methodForSelector:' method"));
- /* Call the verification method, to make sure that the target
- class implements the desired method. */
- argvec[0] = msg_send;
- argvec[1] = target;
- argvec[2] = value_from_longest (long_type, responds_selector);
- argvec[3] = value_from_longest (long_type, selector);
- argvec[4] = 0;
- ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
- if (gnu_runtime)
- {
- /* Function objc_msg_lookup returns a pointer. */
- argvec[0] = ret;
- ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
- }
- if (value_as_long (ret) == 0)
- error (_("Target does not respond to this message selector."));
- /* Call "methodForSelector:" method, to get the address of a
- function method that implements this selector for this
- class. If we can find a symbol at that address, then we
- know the return type, parameter types etc. (that's a good
- thing). */
- argvec[0] = msg_send;
- argvec[1] = target;
- argvec[2] = value_from_longest (long_type, method_selector);
- argvec[3] = value_from_longest (long_type, selector);
- argvec[4] = 0;
- ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
- if (gnu_runtime)
- {
- argvec[0] = ret;
- ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
- }
- /* ret should now be the selector. */
- addr = value_as_long (ret);
- if (addr)
- {
- struct symbol *sym = NULL;
- /* The address might point to a function descriptor;
- resolve it to the actual code address instead. */
- addr = gdbarch_convert_from_func_ptr_addr
- (exp->gdbarch, addr, current_inferior ()->top_target ());
- /* Is it a high_level symbol? */
- sym = find_pc_function (addr);
- if (sym != NULL)
- method = value_of_variable (sym, 0);
- }
- /* If we found a method with symbol information, check to see
- if it returns a struct. Otherwise assume it doesn't. */
- if (method)
- {
- CORE_ADDR funaddr;
- struct type *val_type;
- funaddr = find_function_addr (method, &val_type);
- block_for_pc (funaddr);
- val_type = check_typedef (val_type);
- if ((val_type == NULL)
- || (val_type->code () == TYPE_CODE_ERROR))
- {
- if (expect_type != NULL)
- val_type = expect_type;
- }
- struct_return = using_struct_return (exp->gdbarch, method,
- val_type);
- }
- else if (expect_type != NULL)
- {
- struct_return = using_struct_return (exp->gdbarch, NULL,
- check_typedef (expect_type));
- }
- /* Found a function symbol. Now we will substitute its
- value in place of the message dispatcher (obj_msgSend),
- so that we call the method directly instead of thru
- the dispatcher. The main reason for doing this is that
- we can now evaluate the return value and parameter values
- according to their known data types, in case we need to
- do things like promotion, dereferencing, special handling
- of structs and doubles, etc.
- We want to use the type signature of 'method', but still
- jump to objc_msgSend() or objc_msgSend_stret() to better
- mimic the behavior of the runtime. */
- if (method)
- {
- if (value_type (method)->code () != TYPE_CODE_FUNC)
- error (_("method address has symbol information "
- "with non-function type; skipping"));
- /* Create a function pointer of the appropriate type, and
- replace its value with the value of msg_send or
- msg_send_stret. We must use a pointer here, as
- msg_send and msg_send_stret are of pointer type, and
- the representation may be different on systems that use
- function descriptors. */
- if (struct_return)
- called_method
- = value_from_pointer (lookup_pointer_type (value_type (method)),
- value_as_address (msg_send_stret));
- else
- called_method
- = value_from_pointer (lookup_pointer_type (value_type (method)),
- value_as_address (msg_send));
- }
- else
- {
- if (struct_return)
- called_method = msg_send_stret;
- else
- called_method = msg_send;
- }
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- /* If the return type doesn't look like a function type,
- call an error. This can happen if somebody tries to
- turn a variable into a function call. This is here
- because people often want to call, eg, strcmp, which
- gdb doesn't know is a function. If gdb isn't asked for
- it's opinion (ie. through "whatis"), it won't offer
- it. */
- struct type *callee_type = value_type (called_method);
- if (callee_type && callee_type->code () == TYPE_CODE_PTR)
- callee_type = TYPE_TARGET_TYPE (callee_type);
- callee_type = TYPE_TARGET_TYPE (callee_type);
- if (callee_type)
- {
- if ((callee_type->code () == TYPE_CODE_ERROR) && expect_type)
- return allocate_value (expect_type);
- else
- return allocate_value (callee_type);
- }
- else
- error (_("Expression of type other than "
- "\"method returning ...\" used as a method"));
- }
- /* Now depending on whether we found a symbol for the method,
- we will either call the runtime dispatcher or the method
- directly. */
- args[0] = target;
- args[1] = value_from_longest (long_type, selector);
- if (gnu_runtime && (method != NULL))
- {
- /* Function objc_msg_lookup returns a pointer. */
- struct type *tem_type = value_type (called_method);
- tem_type = lookup_pointer_type (lookup_function_type (tem_type));
- deprecated_set_value_type (called_method, tem_type);
- called_method = call_function_by_hand (called_method, NULL, args);
- }
- return call_function_by_hand (called_method, NULL, args);
- }
- /* Helper function for MULTI_SUBSCRIPT. */
- static struct value *
- eval_multi_subscript (struct type *expect_type, struct expression *exp,
- enum noside noside, value *arg1,
- gdb::array_view<value *> args)
- {
- for (value *arg2 : args)
- {
- if (binop_user_defined_p (MULTI_SUBSCRIPT, arg1, arg2))
- {
- arg1 = value_x_binop (arg1, arg2, MULTI_SUBSCRIPT, OP_NULL, noside);
- }
- else
- {
- arg1 = coerce_ref (arg1);
- struct type *type = check_typedef (value_type (arg1));
- switch (type->code ())
- {
- case TYPE_CODE_PTR:
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_STRING:
- arg1 = value_subscript (arg1, value_as_long (arg2));
- break;
- default:
- if (type->name ())
- error (_("cannot subscript something of type `%s'"),
- type->name ());
- else
- error (_("cannot subscript requested type"));
- }
- }
- }
- return (arg1);
- }
- namespace expr
- {
- value *
- objc_msgcall_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- enum noside sub_no_side = EVAL_NORMAL;
- struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- sub_no_side = EVAL_NORMAL;
- else
- sub_no_side = noside;
- value *target
- = std::get<1> (m_storage)->evaluate (selector_type, exp, sub_no_side);
- if (value_as_long (target) == 0)
- sub_no_side = EVAL_AVOID_SIDE_EFFECTS;
- else
- sub_no_side = noside;
- std::vector<operation_up> &args = std::get<2> (m_storage);
- value **argvec = XALLOCAVEC (struct value *, args.size () + 3);
- argvec[0] = nullptr;
- argvec[1] = nullptr;
- for (int i = 0; i < args.size (); ++i)
- argvec[i + 2] = args[i]->evaluate_with_coercion (exp, sub_no_side);
- argvec[args.size () + 2] = nullptr;
- return eval_op_objc_msgcall (expect_type, exp, noside, std::
- get<0> (m_storage), target,
- gdb::make_array_view (argvec,
- args.size () + 3));
- }
- value *
- multi_subscript_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- value *arg1 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
- std::vector<operation_up> &values = std::get<1> (m_storage);
- value **argvec = XALLOCAVEC (struct value *, values.size ());
- for (int ix = 0; ix < values.size (); ++ix)
- argvec[ix] = values[ix]->evaluate_with_coercion (exp, noside);
- return eval_multi_subscript (expect_type, exp, noside, arg1,
- gdb::make_array_view (argvec, values.size ()));
- }
- value *
- logical_and_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp,
- EVAL_AVOID_SIDE_EFFECTS);
- if (binop_user_defined_p (BINOP_LOGICAL_AND, arg1, arg2))
- {
- arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- return value_x_binop (arg1, arg2, BINOP_LOGICAL_AND, OP_NULL, noside);
- }
- else
- {
- bool tem = value_logical_not (arg1);
- if (!tem)
- {
- arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- tem = value_logical_not (arg2);
- }
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, !tem);
- }
- }
- value *
- logical_or_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp,
- EVAL_AVOID_SIDE_EFFECTS);
- if (binop_user_defined_p (BINOP_LOGICAL_OR, arg1, arg2))
- {
- arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- return value_x_binop (arg1, arg2, BINOP_LOGICAL_OR, OP_NULL, noside);
- }
- else
- {
- bool tem = value_logical_not (arg1);
- if (tem)
- {
- arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- tem = value_logical_not (arg2);
- }
- struct type *type = language_bool_type (exp->language_defn,
- exp->gdbarch);
- return value_from_longest (type, !tem);
- }
- }
- value *
- adl_func_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- std::vector<operation_up> &arg_ops = std::get<2> (m_storage);
- std::vector<value *> args (arg_ops.size ());
- for (int i = 0; i < arg_ops.size (); ++i)
- args[i] = arg_ops[i]->evaluate_with_coercion (exp, noside);
- struct symbol *symp;
- find_overload_match (args, std::get<0> (m_storage).c_str (),
- NON_METHOD,
- nullptr, nullptr,
- nullptr, &symp, nullptr, 0, noside);
- if (symp->type ()->code () == TYPE_CODE_ERROR)
- error_unknown_type (symp->print_name ());
- value *callee = evaluate_var_value (noside, std::get<1> (m_storage), symp);
- return evaluate_subexp_do_call (exp, noside, callee, args,
- nullptr, expect_type);
- }
- /* This function evaluates brace-initializers (in C/C++) for
- structure types. */
- struct value *
- array_operation::evaluate_struct_tuple (struct value *struct_val,
- struct expression *exp,
- enum noside noside, int nargs)
- {
- const std::vector<operation_up> &in_args = std::get<2> (m_storage);
- struct type *struct_type = check_typedef (value_type (struct_val));
- struct type *field_type;
- int fieldno = -1;
- int idx = 0;
- while (--nargs >= 0)
- {
- struct value *val = NULL;
- int bitpos, bitsize;
- bfd_byte *addr;
- fieldno++;
- /* Skip static fields. */
- while (fieldno < struct_type->num_fields ()
- && field_is_static (&struct_type->field (fieldno)))
- fieldno++;
- if (fieldno >= struct_type->num_fields ())
- error (_("too many initializers"));
- field_type = struct_type->field (fieldno).type ();
- if (field_type->code () == TYPE_CODE_UNION
- && struct_type->field (fieldno).name ()[0] == '0')
- error (_("don't know which variant you want to set"));
- /* Here, struct_type is the type of the inner struct,
- while substruct_type is the type of the inner struct.
- These are the same for normal structures, but a variant struct
- contains anonymous union fields that contain substruct fields.
- The value fieldno is the index of the top-level (normal or
- anonymous union) field in struct_field, while the value
- subfieldno is the index of the actual real (named inner) field
- in substruct_type. */
- field_type = struct_type->field (fieldno).type ();
- if (val == 0)
- val = in_args[idx++]->evaluate (field_type, exp, noside);
- /* Now actually set the field in struct_val. */
- /* Assign val to field fieldno. */
- if (value_type (val) != field_type)
- val = value_cast (field_type, val);
- bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno);
- bitpos = struct_type->field (fieldno).loc_bitpos ();
- addr = value_contents_writeable (struct_val).data () + bitpos / 8;
- if (bitsize)
- modify_field (struct_type, addr,
- value_as_long (val), bitpos % 8, bitsize);
- else
- memcpy (addr, value_contents (val).data (),
- TYPE_LENGTH (value_type (val)));
- }
- return struct_val;
- }
- value *
- array_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- int tem;
- int tem2 = std::get<0> (m_storage);
- int tem3 = std::get<1> (m_storage);
- const std::vector<operation_up> &in_args = std::get<2> (m_storage);
- int nargs = tem3 - tem2 + 1;
- struct type *type = expect_type ? check_typedef (expect_type) : nullptr;
- if (expect_type != nullptr
- && type->code () == TYPE_CODE_STRUCT)
- {
- struct value *rec = allocate_value (expect_type);
- memset (value_contents_raw (rec).data (), '\0', TYPE_LENGTH (type));
- return evaluate_struct_tuple (rec, exp, noside, nargs);
- }
- if (expect_type != nullptr
- && type->code () == TYPE_CODE_ARRAY)
- {
- struct type *range_type = type->index_type ();
- struct type *element_type = TYPE_TARGET_TYPE (type);
- struct value *array = allocate_value (expect_type);
- int element_size = TYPE_LENGTH (check_typedef (element_type));
- LONGEST low_bound, high_bound, index;
- if (!get_discrete_bounds (range_type, &low_bound, &high_bound))
- {
- low_bound = 0;
- high_bound = (TYPE_LENGTH (type) / element_size) - 1;
- }
- index = low_bound;
- memset (value_contents_raw (array).data (), 0, TYPE_LENGTH (expect_type));
- for (tem = nargs; --nargs >= 0;)
- {
- struct value *element;
- element = in_args[index - low_bound]->evaluate (element_type,
- exp, noside);
- if (value_type (element) != element_type)
- element = value_cast (element_type, element);
- if (index > high_bound)
- /* To avoid memory corruption. */
- error (_("Too many array elements"));
- memcpy (value_contents_raw (array).data ()
- + (index - low_bound) * element_size,
- value_contents (element).data (),
- element_size);
- index++;
- }
- return array;
- }
- if (expect_type != nullptr
- && type->code () == TYPE_CODE_SET)
- {
- struct value *set = allocate_value (expect_type);
- gdb_byte *valaddr = value_contents_raw (set).data ();
- struct type *element_type = type->index_type ();
- struct type *check_type = element_type;
- LONGEST low_bound, high_bound;
- /* Get targettype of elementtype. */
- while (check_type->code () == TYPE_CODE_RANGE
- || check_type->code () == TYPE_CODE_TYPEDEF)
- check_type = TYPE_TARGET_TYPE (check_type);
- if (!get_discrete_bounds (element_type, &low_bound, &high_bound))
- error (_("(power)set type with unknown size"));
- memset (valaddr, '\0', TYPE_LENGTH (type));
- int idx = 0;
- for (tem = 0; tem < nargs; tem++)
- {
- LONGEST range_low, range_high;
- struct type *range_low_type, *range_high_type;
- struct value *elem_val;
- elem_val = in_args[idx++]->evaluate (element_type, exp, noside);
- range_low_type = range_high_type = value_type (elem_val);
- range_low = range_high = value_as_long (elem_val);
- /* Check types of elements to avoid mixture of elements from
- different types. Also check if type of element is "compatible"
- with element type of powerset. */
- if (range_low_type->code () == TYPE_CODE_RANGE)
- range_low_type = TYPE_TARGET_TYPE (range_low_type);
- if (range_high_type->code () == TYPE_CODE_RANGE)
- range_high_type = TYPE_TARGET_TYPE (range_high_type);
- if ((range_low_type->code () != range_high_type->code ())
- || (range_low_type->code () == TYPE_CODE_ENUM
- && (range_low_type != range_high_type)))
- /* different element modes. */
- error (_("POWERSET tuple elements of different mode"));
- if ((check_type->code () != range_low_type->code ())
- || (check_type->code () == TYPE_CODE_ENUM
- && range_low_type != check_type))
- error (_("incompatible POWERSET tuple elements"));
- if (range_low > range_high)
- {
- warning (_("empty POWERSET tuple range"));
- continue;
- }
- if (range_low < low_bound || range_high > high_bound)
- error (_("POWERSET tuple element out of range"));
- range_low -= low_bound;
- range_high -= low_bound;
- for (; range_low <= range_high; range_low++)
- {
- int bit_index = (unsigned) range_low % TARGET_CHAR_BIT;
- if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
- bit_index = TARGET_CHAR_BIT - 1 - bit_index;
- valaddr[(unsigned) range_low / TARGET_CHAR_BIT]
- |= 1 << bit_index;
- }
- }
- return set;
- }
- value **argvec = XALLOCAVEC (struct value *, nargs);
- for (tem = 0; tem < nargs; tem++)
- {
- /* Ensure that array expressions are coerced into pointer
- objects. */
- argvec[tem] = in_args[tem]->evaluate_with_coercion (exp, noside);
- }
- return value_array (tem2, tem3, argvec);
- }
- value *
- unop_extract_operation::evaluate (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- value *old_value = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- struct type *type = get_type ();
- if (TYPE_LENGTH (type) > TYPE_LENGTH (value_type (old_value)))
- error (_("length type is larger than the value type"));
- struct value *result = allocate_value (type);
- value_contents_copy (result, 0, old_value, 0, TYPE_LENGTH (type));
- return result;
- }
- }
- /* Helper for evaluate_subexp_for_address. */
- static value *
- evaluate_subexp_for_address_base (struct expression *exp, enum noside noside,
- value *x)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- struct type *type = check_typedef (value_type (x));
- if (TYPE_IS_REFERENCE (type))
- return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
- not_lval);
- else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
- return value_zero (lookup_pointer_type (value_type (x)),
- not_lval);
- else
- error (_("Attempt to take address of "
- "value not located in memory."));
- }
- return value_addr (x);
- }
- namespace expr
- {
- value *
- operation::evaluate_for_cast (struct type *expect_type,
- struct expression *exp,
- enum noside noside)
- {
- value *val = evaluate (expect_type, exp, noside);
- return value_cast (expect_type, val);
- }
- value *
- operation::evaluate_for_address (struct expression *exp, enum noside noside)
- {
- value *val = evaluate (nullptr, exp, noside);
- return evaluate_subexp_for_address_base (exp, noside, val);
- }
- value *
- scope_operation::evaluate_for_address (struct expression *exp,
- enum noside noside)
- {
- value *x = value_aggregate_elt (std::get<0> (m_storage),
- std::get<1> (m_storage).c_str (),
- NULL, 1, noside);
- if (x == NULL)
- error (_("There is no field named %s"), std::get<1> (m_storage).c_str ());
- return x;
- }
- value *
- unop_ind_base_operation::evaluate_for_address (struct expression *exp,
- enum noside noside)
- {
- value *x = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- /* We can't optimize out "&*" if there's a user-defined operator*. */
- if (unop_user_defined_p (UNOP_IND, x))
- {
- x = value_x_unop (x, UNOP_IND, noside);
- return evaluate_subexp_for_address_base (exp, noside, x);
- }
- return coerce_array (x);
- }
- value *
- var_msym_value_operation::evaluate_for_address (struct expression *exp,
- enum noside noside)
- {
- const bound_minimal_symbol &b = std::get<0> (m_storage);
- value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym);
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- struct type *type = lookup_pointer_type (value_type (val));
- return value_zero (type, not_lval);
- }
- else
- return value_addr (val);
- }
- value *
- unop_memval_operation::evaluate_for_address (struct expression *exp,
- enum noside noside)
- {
- return value_cast (lookup_pointer_type (std::get<1> (m_storage)),
- std::get<0> (m_storage)->evaluate (nullptr, exp, noside));
- }
- value *
- unop_memval_type_operation::evaluate_for_address (struct expression *exp,
- enum noside noside)
- {
- value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp,
- EVAL_AVOID_SIDE_EFFECTS);
- struct type *type = value_type (typeval);
- return value_cast (lookup_pointer_type (type),
- std::get<1> (m_storage)->evaluate (nullptr, exp, noside));
- }
- value *
- var_value_operation::evaluate_for_address (struct expression *exp,
- enum noside noside)
- {
- symbol *var = std::get<0> (m_storage).symbol;
- /* C++: The "address" of a reference should yield the address
- * of the object pointed to. Let value_addr() deal with it. */
- if (TYPE_IS_REFERENCE (var->type ()))
- return operation::evaluate_for_address (exp, noside);
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- struct type *type = lookup_pointer_type (var->type ());
- enum address_class sym_class = var->aclass ();
- if (sym_class == LOC_CONST
- || sym_class == LOC_CONST_BYTES
- || sym_class == LOC_REGISTER)
- error (_("Attempt to take address of register or constant."));
- return value_zero (type, not_lval);
- }
- else
- return address_of_variable (var, std::get<0> (m_storage).block);
- }
- value *
- var_value_operation::evaluate_with_coercion (struct expression *exp,
- enum noside noside)
- {
- struct symbol *var = std::get<0> (m_storage).symbol;
- struct type *type = check_typedef (var->type ());
- if (type->code () == TYPE_CODE_ARRAY
- && !type->is_vector ()
- && CAST_IS_CONVERSION (exp->language_defn))
- {
- struct value *val = address_of_variable (var,
- std::get<0> (m_storage).block);
- return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), val);
- }
- return evaluate (nullptr, exp, noside);
- }
- }
- /* Helper function for evaluating the size of a type. */
- static value *
- evaluate_subexp_for_sizeof_base (struct expression *exp, struct type *type)
- {
- /* FIXME: This should be size_t. */
- struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
- /* $5.3.3/2 of the C++ Standard (n3290 draft) says of sizeof:
- "When applied to a reference or a reference type, the result is
- the size of the referenced type." */
- type = check_typedef (type);
- if (exp->language_defn->la_language == language_cplus
- && (TYPE_IS_REFERENCE (type)))
- type = check_typedef (TYPE_TARGET_TYPE (type));
- return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
- }
- namespace expr
- {
- value *
- operation::evaluate_for_sizeof (struct expression *exp, enum noside noside)
- {
- value *val = evaluate (nullptr, exp, EVAL_AVOID_SIDE_EFFECTS);
- return evaluate_subexp_for_sizeof_base (exp, value_type (val));
- }
- value *
- var_msym_value_operation::evaluate_for_sizeof (struct expression *exp,
- enum noside noside)
- {
- const bound_minimal_symbol &b = std::get<0> (m_storage);
- value *mval = evaluate_var_msym_value (noside, b.objfile, b.minsym);
- struct type *type = value_type (mval);
- if (type->code () == TYPE_CODE_ERROR)
- error_unknown_type (b.minsym->print_name ());
- /* FIXME: This should be size_t. */
- struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
- return value_from_longest (size_type, TYPE_LENGTH (type));
- }
- value *
- subscript_operation::evaluate_for_sizeof (struct expression *exp,
- enum noside noside)
- {
- if (noside == EVAL_NORMAL)
- {
- value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
- EVAL_AVOID_SIDE_EFFECTS);
- struct type *type = check_typedef (value_type (val));
- if (type->code () == TYPE_CODE_ARRAY)
- {
- type = check_typedef (TYPE_TARGET_TYPE (type));
- if (type->code () == TYPE_CODE_ARRAY)
- {
- type = type->index_type ();
- /* Only re-evaluate the right hand side if the resulting type
- is a variable length type. */
- if (type->bounds ()->flag_bound_evaluated)
- {
- val = evaluate (nullptr, exp, EVAL_NORMAL);
- /* FIXME: This should be size_t. */
- struct type *size_type
- = builtin_type (exp->gdbarch)->builtin_int;
- return value_from_longest
- (size_type, (LONGEST) TYPE_LENGTH (value_type (val)));
- }
- }
- }
- }
- return operation::evaluate_for_sizeof (exp, noside);
- }
- value *
- unop_ind_base_operation::evaluate_for_sizeof (struct expression *exp,
- enum noside noside)
- {
- value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
- EVAL_AVOID_SIDE_EFFECTS);
- struct type *type = check_typedef (value_type (val));
- if (!type->is_pointer_or_reference ()
- && type->code () != TYPE_CODE_ARRAY)
- error (_("Attempt to take contents of a non-pointer value."));
- type = TYPE_TARGET_TYPE (type);
- if (is_dynamic_type (type))
- type = value_type (value_ind (val));
- /* FIXME: This should be size_t. */
- struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
- return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
- }
- value *
- unop_memval_operation::evaluate_for_sizeof (struct expression *exp,
- enum noside noside)
- {
- return evaluate_subexp_for_sizeof_base (exp, std::get<1> (m_storage));
- }
- value *
- unop_memval_type_operation::evaluate_for_sizeof (struct expression *exp,
- enum noside noside)
- {
- value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp,
- EVAL_AVOID_SIDE_EFFECTS);
- return evaluate_subexp_for_sizeof_base (exp, value_type (typeval));
- }
- value *
- var_value_operation::evaluate_for_sizeof (struct expression *exp,
- enum noside noside)
- {
- struct type *type = std::get<0> (m_storage).symbol->type ();
- if (is_dynamic_type (type))
- {
- value *val = evaluate (nullptr, exp, EVAL_NORMAL);
- type = value_type (val);
- if (type->code () == TYPE_CODE_ARRAY)
- {
- /* FIXME: This should be size_t. */
- struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
- if (type_not_allocated (type) || type_not_associated (type))
- return value_zero (size_type, not_lval);
- else if (is_dynamic_type (type->index_type ())
- && type->bounds ()->high.kind () == PROP_UNDEFINED)
- return allocate_optimized_out_value (size_type);
- }
- }
- return evaluate_subexp_for_sizeof_base (exp, type);
- }
- value *
- var_msym_value_operation::evaluate_for_cast (struct type *to_type,
- struct expression *exp,
- enum noside noside)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (to_type, not_lval);
- const bound_minimal_symbol &b = std::get<0> (m_storage);
- value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym);
- val = value_cast (to_type, val);
- /* Don't allow e.g. '&(int)var_with_no_debug_info'. */
- if (VALUE_LVAL (val) == lval_memory)
- {
- if (value_lazy (val))
- value_fetch_lazy (val);
- VALUE_LVAL (val) = not_lval;
- }
- return val;
- }
- value *
- var_value_operation::evaluate_for_cast (struct type *to_type,
- struct expression *exp,
- enum noside noside)
- {
- value *val = evaluate_var_value (noside,
- std::get<0> (m_storage).block,
- std::get<0> (m_storage).symbol);
- val = value_cast (to_type, val);
- /* Don't allow e.g. '&(int)var_with_no_debug_info'. */
- if (VALUE_LVAL (val) == lval_memory)
- {
- if (value_lazy (val))
- value_fetch_lazy (val);
- VALUE_LVAL (val) = not_lval;
- }
- return val;
- }
- }
- /* Parse a type expression in the string [P..P+LENGTH). */
- struct type *
- parse_and_eval_type (const char *p, int length)
- {
- char *tmp = (char *) alloca (length + 4);
- tmp[0] = '(';
- memcpy (tmp + 1, p, length);
- tmp[length + 1] = ')';
- tmp[length + 2] = '0';
- tmp[length + 3] = '\0';
- expression_up expr = parse_expression (tmp);
- expr::unop_cast_operation *op
- = dynamic_cast<expr::unop_cast_operation *> (expr->op.get ());
- if (op == nullptr)
- error (_("Internal error in eval_type."));
- return op->get_type ();
- }
|