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 }