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, 34 enum function_role function, FILE *fp, 35 struct interface *iface) 36 { 37 int cpp = (conf.language == CPP_LANGUAGE); 38 int have_init_param = (conf.language == C_LANGUAGE); 39 int declaration = (role & DECLARATION_ROLE); 40 int member = (role & MEMBER_ROLE); 41 int server = (component == SERVER_ROLE); 42 43 /* Explicit completion functions only employ input/inout parameters. */ 44 45 int completion = (function == COMPLETION_ROLE); 46 enum specifier direction = completion ? IN_PARAMETER : ANY_PARAMETER; 47 48 /* Indent and provide a qualifier for C++ class declarations. */ 49 50 char *qualifier = (cpp && declaration) ? " virtual " : member ? " " : ""; 51 52 /* Structure the function name appropriately. */ 53 54 char *opname = get_signature_operation_name(iface, sig, component, role, 55 conf.language); 56 57 /* Introduce an initial parameter for the component state. */ 58 59 if (!cpp && member) 60 fprintf(fp, interface_struct_member_function_signature_prologue, opname); 61 else 62 fprintf(fp, interface_function_signature_prologue, qualifier, opname); 63 64 if (have_init_param) 65 write_initial_parameter(iface->name, fp); 66 67 /* Emit the parameters. */ 68 69 write_parameters(sig->parameters, fp, SIGNATURE_ROLE, function, direction, 70 have_init_param); 71 72 fputs(")", fp); 73 74 /* Add a body for the function, this being used to define unimplemented 75 methods in C++. The client has method definitions and therefore normal 76 virtual methods. */ 77 78 if (cpp && declaration && server) 79 write_interface_unimplemented_method(sig, direction, fp); 80 else 81 fputs(get_signature_terminator(role), fp); 82 83 free(opname); 84 } 85 86 /* Write an unimplemented member function body for a C++ interface. */ 87 88 void write_interface_unimplemented_method(struct signature *sig, 89 enum specifier direction, FILE *fp) 90 { 91 struct parameter *param; 92 93 fputs(interface_unimplemented_method_prologue_cpp, fp); 94 95 for (param = sig->parameters; param != NULL; param = param->tail) 96 { 97 if (param->specifier & direction) 98 fprintf(fp, interface_unused_parameter, get_parameter_name(param->identifiers)); 99 } 100 101 fputs(interface_unimplemented_method_epilogue_cpp, fp); 102 } 103 104 /* Write the initial parameter in an interface signature. */ 105 106 void write_initial_parameter(const char *name, FILE *fp) 107 { 108 if (conf.language == CPP_LANGUAGE) 109 fprintf(fp, "%s *_self", name); 110 else 111 fprintf(fp, "ref_%s _self", name); 112 } 113 114 /* Generate signatures. */ 115 116 void write_signatures(struct signature *sig, enum signature_role role, FILE *fp, 117 struct interface *iface, 118 void (*write_signature)(struct signature *, 119 enum signature_role role, 120 FILE *, struct interface *)) 121 { 122 if (sig == NULL) 123 return; 124 125 write_signature(sig, role, fp, iface); 126 write_signatures(sig->tail, role, fp, iface, write_signature); 127 } 128 129 130 131 /* Generate parameters in each function signature. */ 132 133 void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role, 134 enum function_role function, enum specifier direction, 135 int continuing) 136 { 137 for (; param != NULL; param = param->tail) 138 { 139 if (param->specifier & direction) 140 { 141 if (continuing) 142 fputs(", ", fp); 143 else 144 continuing = 1; 145 146 write_parameter(param, fp, role, function); 147 } 148 } 149 } 150 151 /* Generate a parameter in a signature or invocation. */ 152 153 void write_parameter(struct parameter *param, FILE *fp, 154 enum parameter_role role, enum function_role function) 155 { 156 struct identifier *ident = param->identifiers; 157 char *type; 158 int invocation = (role == INVOCATION_ROLE); 159 int first = 1; 160 161 while (ident != NULL) 162 { 163 /* Put spaces between each type identifier. */ 164 165 if (!invocation) 166 { 167 if (first) 168 first = 0; 169 else 170 fputs(" ", fp); 171 } 172 173 /* Emit type identifiers for signatures. */ 174 175 if (ident->tail != NULL) 176 { 177 if (!invocation) 178 fputs(ident->identifier, fp); 179 } 180 181 /* Emit the parameter name. */ 182 183 else 184 { 185 /* Items must have their type identifiers restored. */ 186 187 if ((param->cls & ITEM_CLASS) && !invocation) 188 { 189 type = param->cls == FPAGE_ITEM ? L4_FPAGE_TYPE : L4_CAP_TYPE; 190 fputs(type, fp); 191 fputs(" ", fp); 192 } 193 194 /* Emit the decoration and parameter name. */ 195 196 fprintf(fp, "%s%s", get_parameter_decoration(param, role, function), 197 ident->identifier); 198 } 199 200 ident = ident->tail; 201 } 202 } 203 204 /* Write structure members for word data structures or variable declarations for 205 parameters. */ 206 207 void write_declarations(struct parameter *param, enum specifier direction, 208 enum parameter_class cls, FILE *fp) 209 { 210 for (; param != NULL; param = param->tail) 211 { 212 if ((param->specifier & direction) && (param->cls & cls)) 213 { 214 fputs(INDENT_MEMBER, fp); 215 write_parameter(param, fp, STRUCTURE_ROLE, GENERAL_FUNCTION_ROLE); 216 fputs(COMPLETE_MEMBER, fp); 217 } 218 } 219 }