1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 * 25 */ 26 27 package jdk.incubator.jextract; 28 29 import jdk.incubator.foreign.FunctionDescriptor; 30 import jdk.incubator.foreign.MemoryLayout; 31 import jdk.incubator.foreign.ValueLayout; 32 import jdk.internal.jextract.impl.TypeImpl; 33 import jdk.internal.jextract.impl.UnsupportedLayouts; 34 35 import java.util.List; 36 import java.util.Optional; 37 import java.util.OptionalLong; 38 import java.util.function.Supplier; 39 import java.util.stream.Collectors; 40 import java.util.stream.Stream; 41 42 /** 43 * Instances of this class are used to model types in the foreign language. 44 * Instances of this class support the <em>visitor</em> pattern (see {@link Type#accept(Type.Visitor, Object)} and 45 * {@link Type.Visitor}). 46 */ 47 public interface Type { 48 49 /** 50 * Is this type the erroneous type? 51 * @return true, if this type is the erroneous type. 52 */ 53 boolean isErroneous(); 54 55 /** 56 * Entry point for visiting type instances. 57 * @param visitor the type visitor. 58 * @param data optional data to be passed to the visitor. 59 * @param <R> the visitor's return type. 60 * @param <D> the visitor's argument type. 61 * @return the result of visiting this type through the specified type visitor. 62 */ 63 <R,D> R accept(Visitor<R, D> visitor, D data); 64 65 /** 66 * Compares the specified object with this Type for equality. Returns 67 * {@code true} if and only if the specified object is also a Type and both 68 * the Types are <i>equal</i>. 69 * 70 * @param o the object to be compared for equality with this Type 71 * @return {@code true} if the specified object is equal to this Type 72 */ 73 boolean equals(Object o); 74 75 /** 76 * Returns the hash code value for this Type. 77 * 78 * @return the hash code value for this Type. 79 */ 80 int hashCode(); 81 82 /** 83 * A primitive type. 84 */ 85 interface Primitive extends Type { 86 87 /** 88 * The primitive type kind. 89 */ 90 enum Kind { 91 /** 92 * {@code void} type. 93 */ 94 Void("void", null), 95 /** 96 * {@code Bool} type. 97 */ 98 Bool("_Bool", ValueLayout.JAVA_BOOLEAN), 99 /** 100 * {@code char} type. 101 */ 102 Char("char", ValueLayout.JAVA_BYTE), 103 /** 104 * {@code char16} type. 105 */ 106 Char16("char16", UnsupportedLayouts.CHAR16), 107 /** 108 * {@code short} type. 109 */ 110 Short("short", ValueLayout.JAVA_SHORT.withBitAlignment(16)), 111 /** 112 * {@code int} type. 113 */ 114 Int("int", ValueLayout.JAVA_INT.withBitAlignment(32)), 115 /** 116 * {@code long} type. 117 */ 118 Long("long", TypeImpl.IS_WINDOWS ? 119 ValueLayout.JAVA_INT.withBitAlignment(32) : 120 ValueLayout.JAVA_LONG.withBitAlignment(64)), 121 /** 122 * {@code long long} type. 123 */ 124 LongLong("long long", ValueLayout.JAVA_LONG.withBitAlignment(64)), 125 /** 126 * {@code int128} type. 127 */ 128 Int128("__int128", UnsupportedLayouts.__INT128), 129 /** 130 * {@code float} type. 131 */ 132 Float("float", ValueLayout.JAVA_FLOAT.withBitAlignment(32)), 133 /** 134 * {@code double} type. 135 */ 136 Double("double", ValueLayout.JAVA_DOUBLE.withBitAlignment(64)), 137 /** 138 * {@code long double} type. 139 */ 140 LongDouble("long double", UnsupportedLayouts.LONG_DOUBLE), 141 /** 142 * {@code float128} type. 143 */ 144 Float128("float128", UnsupportedLayouts._FLOAT128), 145 /** 146 * {@code float16} type. 147 */ 148 HalfFloat("__fp16", UnsupportedLayouts.__FP16), 149 /** 150 * {@code wchar} type. 151 */ 152 WChar("wchar_t", UnsupportedLayouts.WCHAR_T); 153 154 private final String typeName; 155 private final MemoryLayout layout; 156 157 Kind(String typeName, MemoryLayout layout) { 158 this.typeName = typeName; 159 this.layout = layout; 160 } 161 162 public String typeName() { 163 return typeName; 164 } 165 166 /** 167 * The primitive type (optional) layout. 168 * @return The primitive type (optional) layout. 169 */ 170 public Optional<MemoryLayout> layout() { 171 return Optional.ofNullable(layout); 172 } 173 } 174 175 /** 176 * The primitive type kind. 177 * @return The primitive type kind. 178 */ 179 Kind kind(); 180 } 181 182 /** 183 * Instances of this class are used to model types which are associated to a declaration in the foreign language 184 * (see {@link Declaration}). 185 */ 186 interface Declared extends Type { 187 /** 188 * The declaration to this type refers to. 189 * @return The declaration to this type refers to. 190 */ 191 Declaration.Scoped tree(); 192 } 193 194 /** 195 * A function type. 196 */ 197 interface Function extends Type { 198 /** 199 * Is this function type a variable-arity? 200 * @return true, if this function type is a variable-arity. 201 */ 202 boolean varargs(); 203 204 /** 205 * The function formal parameter types. 206 * @return The function formal parameter types. 207 */ 208 List<Type> argumentTypes(); 209 210 /** 211 * The function return type. 212 * @return The function return type. 213 */ 214 Type returnType(); 215 216 /** 217 * Names of function parameters (from typedef), if any 218 * @return The optional list of function parameter names. 219 */ 220 Optional<List<String>> parameterNames(); 221 222 /** 223 * Returns a Function type that has the given parameter names. 224 * 225 * @param paramNames parameter names for this function type. 226 * @return new Function type with the given parameter names. 227 */ 228 Function withParameterNames(List<String> paramNames); 229 } 230 231 /** 232 * An array type. Array types feature an element type and an optional size. As such they can also be used to 233 * model array types. 234 */ 235 interface Array extends Type { 236 237 /** 238 * The array type kind. 239 */ 240 enum Kind { 241 /** 242 * Vector kind. 243 */ 244 VECTOR, 245 /** 246 * Array kind. 247 */ 248 ARRAY, 249 /** 250 * Incomplete array kind. 251 */ 252 INCOMPLETE_ARRAY; 253 } 254 255 /** 256 * The array type kind. 257 * @return The array type kind. 258 */ 259 Kind kind(); 260 261 /** 262 * The (optional) array element count. 263 * @return The (optional) array element count. 264 * 265 * @implSpec an element count is present if the array type kind is one of {@link Kind#VECTOR}, {@link Kind#ARRAY}. 266 */ 267 OptionalLong elementCount(); 268 269 /** 270 * The array type element type. 271 * @return The array type element type. 272 */ 273 Type elementType(); 274 } 275 276 /** 277 * A delegated type is used to model a type which contains an indirection to some other underlying type. For instance, 278 * a delegated type can be used to model foreign pointers, where the indirection is used to model the pointee type. 279 */ 280 interface Delegated extends Type { 281 282 /** 283 * The delegated type kind. 284 */ 285 enum Kind { 286 /** 287 * Type-defined type. 288 */ 289 TYPEDEF, 290 /** 291 * Pointer type. 292 */ 293 POINTER, 294 /** 295 * Signed type. 296 */ 297 SIGNED, 298 /** 299 * Unsigned type. 300 */ 301 UNSIGNED, 302 /** 303 * Atomic type. 304 */ 305 ATOMIC, 306 /** 307 * Volatile type. 308 */ 309 VOLATILE, 310 /** 311 * Complex type. 312 */ 313 COMPLEX; 314 } 315 316 /** 317 * The delegated type kind. 318 * @return The delegated type kind. 319 */ 320 Kind kind(); 321 322 /** 323 * The delegated type (optional) name. 324 * @return The delegated type (optional) name. 325 * 326 * @implSpec an element count is present if the array type kind is one of {@link Kind#TYPEDEF}. 327 */ 328 Optional<String> name(); 329 330 /** 331 * The delegated type underlying type. 332 * @return The delegated type underlying type. 333 */ 334 Type type(); 335 } 336 337 /** 338 * Type visitor interface. 339 * @param <R> the visitor's return type. 340 * @param <P> the visitor's parameter type. 341 */ 342 interface Visitor<R,P> { 343 /** 344 * Visit a primitive type. 345 * @param t the primitive type. 346 * @param p the visitor parameter. 347 * @return the result of visiting the given primitive type through this visitor object. 348 */ 349 default R visitPrimitive(Primitive t, P p) { return visitType(t, p); } 350 351 /** 352 * Visit a function type. 353 * @param t the function type. 354 * @param p the visitor parameter. 355 * @return the result of visiting the given function type through this visitor object. 356 */ 357 default R visitFunction(Function t, P p) { return visitType(t, p); } 358 359 /** 360 * Visit a declared type. 361 * @param t the declared type. 362 * @param p the visitor parameter. 363 * @return the result of visiting the given declared type through this visitor object. 364 */ 365 default R visitDeclared(Declared t, P p) { return visitType(t, p); } 366 367 /** 368 * Visit a delegated type. 369 * @param t the delegated type. 370 * @param p the visitor parameter. 371 * @return the result of visiting the given delegated type through this visitor object. 372 */ 373 default R visitDelegated(Delegated t, P p) { return visitType(t, p); } 374 375 /** 376 * Visit an array type. 377 * @param t the array type. 378 * @param p the visitor parameter. 379 * @return the result of visiting the given array type through this visitor object. 380 */ 381 default R visitArray(Array t, P p) { return visitType(t, p); } 382 383 /** 384 * Visit a type. 385 * @param t the type. 386 * @param p the visitor parameter. 387 * @return the result of visiting the given type through this visitor object. 388 */ 389 default R visitType(Type t, P p) { throw new UnsupportedOperationException(); } 390 } 391 392 /** 393 * Compute the layout for a given type. 394 * @param t the type. 395 * @return the layout for given type. 396 */ 397 static Optional<MemoryLayout> layoutFor(Type t) { 398 return TypeImpl.getLayout(t); 399 } 400 401 /** 402 * Compute the function descriptor for a given function type. 403 * @param function the function type. 404 * @return the function descriptor for given function type. 405 */ 406 static Optional<FunctionDescriptor> descriptorFor(Function function) { 407 return TypeImpl.getDescriptor(function); 408 } 409 410 /** 411 * Create the {@code void} type. 412 * @return the {@code void} type. 413 */ 414 static Type.Primitive void_() { 415 return new TypeImpl.PrimitiveImpl(Type.Primitive.Kind.Void); 416 } 417 418 /** 419 * Creates a new primitive type given kind. 420 * @param kind the primitive type kind. 421 * @return a new primitive type with given kind. 422 */ 423 static Type.Primitive primitive(Type.Primitive.Kind kind) { 424 return new TypeImpl.PrimitiveImpl(kind); 425 } 426 427 /** 428 * Creates a new qualified type given kind and underlying type. 429 * @param kind the qualified type kind. 430 * @param type the qualified type underlying type. 431 * @return a new qualified type with given name and underlying type. 432 */ 433 static Type.Delegated qualified(Type.Delegated.Kind kind, Type type) { 434 return new TypeImpl.QualifiedImpl(kind, type); 435 } 436 437 /** 438 * Creates a new typedef type given name and underlying type. 439 * @param name the typedef type name. 440 * @param aliased the typeef type underlying type. 441 * @return a new typedef type with given name and underlying type. 442 */ 443 static Type.Delegated typedef(String name, Type aliased) { 444 return new TypeImpl.QualifiedImpl(Delegated.Kind.TYPEDEF, name, aliased); 445 } 446 447 /** 448 * Creates a new pointer type with no associated pointee information. 449 * @return a new pointer type with no associated pointee information. 450 */ 451 static Type.Delegated pointer() { 452 return new TypeImpl.PointerImpl(() -> new TypeImpl.PrimitiveImpl(Type.Primitive.Kind.Void)); 453 } 454 455 /** 456 * Creates a new pointer type with given pointee type. 457 * @param pointee the pointee type. 458 * @return a new pointer type with given pointee type. 459 */ 460 static Type.Delegated pointer(Type pointee) { 461 return new TypeImpl.PointerImpl(() -> pointee); 462 } 463 464 /** 465 * Creates a new pointer type with given pointee type. 466 * @param pointee factory to (lazily) build the pointee type. 467 * @return a new pointer type with given pointee type (lazily built from factory). 468 */ 469 static Type.Delegated pointer(Supplier<Type> pointee) { 470 return new TypeImpl.PointerImpl(pointee); 471 } 472 473 /** 474 * Creates a new function type with given parameter types and return type. 475 * @param varargs is this function type variable-arity? 476 * @param returnType the function type return type. 477 * @param arguments the function type formal parameter types. 478 * @return a new function type with given parameter types and return type. 479 */ 480 static Type.Function function(boolean varargs, Type returnType, Type... arguments) { 481 return new TypeImpl.FunctionImpl(varargs, Stream.of(arguments).collect(Collectors.toList()), returnType, null); 482 } 483 484 /** 485 * Creates a new declared type with given foreign declaration. 486 * @param tree the foreign declaration the type refers to. 487 * @return a new declared type with given foreign declaration. 488 */ 489 static Type.Declared declared(Declaration.Scoped tree) { 490 return new TypeImpl.DeclaredImpl(tree); 491 } 492 493 /** 494 * Creates a new vector type with given element count and element type. 495 * @param elementCount the vector type element count. 496 * @param elementType the vector type element type. 497 * @return a new vector type with given element count and element type. 498 */ 499 static Type.Array vector(long elementCount, Type elementType) { 500 return new TypeImpl.ArrayImpl(Array.Kind.VECTOR, elementCount, elementType); 501 } 502 503 /** 504 * Creates a new array type with given element count and element type. 505 * @param elementCount the array type element count. 506 * @param elementType the array type element type. 507 * @return a new array type with given element count and element type. 508 */ 509 static Type.Array array(long elementCount, Type elementType) { 510 return new TypeImpl.ArrayImpl(Array.Kind.ARRAY, elementCount, elementType); 511 } 512 513 /** 514 * Creates a new array type with given element type. 515 * @param elementType the array type element type. 516 * @return a new array type with given element type. 517 */ 518 static Type.Array array(Type elementType) { 519 return new TypeImpl.ArrayImpl(Array.Kind.INCOMPLETE_ARRAY, elementType); 520 } 521 522 /** 523 * Creates an erroneous type. 524 * @return an erroneous type. 525 */ 526 static Type error() { 527 return TypeImpl.ERROR; 528 } 529 }