1 /* 2 * Generation of declaration elements such as parameters and members. 3 * 4 * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <stdlib.h> 23 #include "common.h" 24 #include "config.h" 25 #include "declaration.h" 26 #include "templates.h" 27 28 29 30 /* Generate each operation signature for use in defining an interface. */ 31 32 void write_interface_signature(struct signature *sig, enum signature_role role, 33 enum component_role component, FILE *fp, 34 struct interface *iface) 35 { 36 int cpp = (conf.language == CPP_LANGUAGE); 37 int have_init_param = (conf.language == C_LANGUAGE); 38 int declaration = (role & DECLARATION_ROLE); 39 int member = (role & MEMBER_ROLE); 40 int server = (component == SERVER_ROLE); 41 int completion = have_attribute(sig->attributes, "completion"); 42 enum specifier direction = (server && completion) ? IN_PARAMETER : ANY_PARAMETER; 43 enum function_role function = (server && completion) ? COMPLETION_ROLE : GENERAL_FUNCTION_ROLE; 44 45 /* Indent and provide a qualifier for C++ class declarations. */ 46 47 char *qualifier = (cpp && declaration) ? " virtual " : member ? " " : ""; 48 49 /* Structure the function name appropriately. */ 50 51 char *opname = get_signature_operation_name(iface, sig, component, role, 52 conf.language); 53 54 /* Introduce an initial parameter for the component state. */ 55 56 if (!cpp && member) 57 fprintf(fp, interface_struct_member_function_signature_prologue, opname); 58 else 59 fprintf(fp, interface_function_signature_prologue, qualifier, opname); 60 61 if (have_init_param) 62 write_initial_parameter(iface->name, fp); 63 64 /* Emit the parameters. */ 65 66 write_parameters(sig->parameters, fp, SIGNATURE_ROLE, function, direction, 67 have_init_param); 68 69 fputs(")", fp); 70 71 /* Add a body for the function, this being used to define unimplemented 72 methods in C++. The client has method definitions and therefore normal 73 virtual methods. */ 74 75 if (cpp && declaration && server) 76 write_interface_unimplemented_method(sig, direction, fp); 77 else 78 fputs(get_signature_terminator(role), fp); 79 80 free(opname); 81 } 82 83 /* Write an unimplemented member function body for a C++ interface. */ 84 85 void write_interface_unimplemented_method(struct signature *sig, 86 enum specifier direction, FILE *fp) 87 { 88 struct parameter *param; 89 90 fputs(interface_unimplemented_method_prologue_cpp, fp); 91 92 for (param = sig->parameters; param != NULL; param = param->tail) 93 { 94 if (param->specifier & direction) 95 fprintf(fp, interface_unused_parameter, get_parameter_name(param->identifiers)); 96 } 97 98 fputs(interface_unimplemented_method_epilogue_cpp, fp); 99 } 100 101 /* Write the initial parameter in an interface signature. */ 102 103 void write_initial_parameter(const char *name, FILE *fp) 104 { 105 if (conf.language == CPP_LANGUAGE) 106 fprintf(fp, "%s *_self", name); 107 else 108 fprintf(fp, "ref_%s _self", name); 109 } 110 111 /* Generate signatures. */ 112 113 void write_signatures(struct signature *sig, enum signature_role role, FILE *fp, 114 struct interface *iface, 115 void (*write_signature)(struct signature *, 116 enum signature_role role, 117 FILE *, struct interface *)) 118 { 119 if (sig == NULL) 120 return; 121 122 write_signature(sig, role, fp, iface); 123 write_signatures(sig->tail, role, fp, iface, write_signature); 124 } 125 126 127 128 /* Generate parameters in each function signature. */ 129 130 void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role, 131 enum function_role function, enum specifier direction, 132 int continuing) 133 { 134 for (; param != NULL; param = param->tail) 135 { 136 if (param->specifier & direction) 137 { 138 if (continuing) 139 fputs(", ", fp); 140 else 141 continuing = 1; 142 143 write_parameter(param, fp, role, function); 144 } 145 } 146 } 147 148 /* Generate a parameter in a signature or invocation. */ 149 150 void write_parameter(struct parameter *param, FILE *fp, 151 enum parameter_role role, enum function_role function) 152 { 153 struct identifier *ident = param->identifiers; 154 char *type; 155 int invocation = (role == INVOCATION_ROLE); 156 int first = 1; 157 158 while (ident != NULL) 159 { 160 /* Put spaces between each type identifier. */ 161 162 if (!invocation) 163 { 164 if (first) 165 first = 0; 166 else 167 fputs(" ", fp); 168 } 169 170 /* Emit type identifiers for signatures. */ 171 172 if (ident->tail != NULL) 173 { 174 if (!invocation) 175 fputs(ident->identifier, fp); 176 } 177 178 /* Emit the parameter name. */ 179 180 else 181 { 182 /* Items must have their type identifiers restored. */ 183 184 if ((param->cls & ITEM_CLASS) && !invocation) 185 { 186 type = param->cls == FPAGE_ITEM ? L4_FPAGE_TYPE : L4_CAP_TYPE; 187 fputs(type, fp); 188 fputs(" ", fp); 189 } 190 191 /* Emit the decoration and parameter name. */ 192 193 fprintf(fp, "%s%s", get_parameter_decoration(param, role, function), 194 ident->identifier); 195 } 196 197 ident = ident->tail; 198 } 199 } 200 201 /* Write structure members for word data structures or variable declarations for 202 parameters. */ 203 204 void write_declarations(struct parameter *param, enum specifier direction, 205 enum parameter_class cls, FILE *fp) 206 { 207 for (; param != NULL; param = param->tail) 208 { 209 if ((param->specifier & direction) && (param->cls & cls)) 210 { 211 fputs(INDENT_MEMBER, fp); 212 write_parameter(param, fp, STRUCTURE_ROLE, GENERAL_FUNCTION_ROLE); 213 fputs(COMPLETE_MEMBER, fp); 214 } 215 } 216 }