+ case PSI_T_FUNCTION:
+ if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.call->name)) {
+ size_t i, argc;
+ struct psi_cpp_macro_call *call = exp->data.call;
+
+ for (i = 0, argc = psi_plist_count(call->args); i < argc; ++i) {
+ struct psi_num_exp *arg;
+
+ if (!psi_plist_get(call->args, i, &arg)) {
+ return false;
+ }
+ if (!psi_num_exp_validate(data, arg, scope)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (psi_builtin_exists(exp->data.call->name)) {
+ exp->data.call->builtin = psi_builtin_get(exp->data.call->name);
+ return true;
+ }
+ return false;
+
+ case PSI_T_DEFINE:
+ if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.numb)) {
+ define: ;
+ if (!scope->macro || !zend_string_equals(scope->macro->token->text, exp->data.numb)) {
+ return true;
+ }
+ /* #define foo foo */
+ }
+ while (psi_plist_get(data->enums, i++, &enm)) {
+ struct psi_validate_scope enum_scope = *scope;
+ enum_scope.current_enum = enm;
+ if (psi_number_validate_enum(data, exp, &enum_scope)) {
+ return true;
+ }
+ }
+ return false;
+
+ case PSI_T_SIZEOF:
+ if (psi_decl_type_validate(data, exp->data.dtyp, NULL, scope)) {
+ struct psi_decl_type *dtyp = exp->data.dtyp;
+
+ exp->type = PSI_T_UINT64;
+ exp->data.ival.u64 = psi_decl_type_get_size(dtyp, NULL);
+ psi_decl_type_free(&dtyp);
+ return true;
+ } else {
+ struct psi_decl_type *dtyp = exp->data.dtyp;
+
+ data->error(data, exp->token, PSI_WARNING,
+ "Cannot compute sizeof(%s) (%u)", dtyp->name->val, dtyp->type);
+
+ exp->type = PSI_T_UINT8;
+ exp->data.ival.u8 = 0;
+ psi_decl_type_free(&dtyp);
+ }
+ break;
+