1 /*
2  * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * - Redistribution of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistribution in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in the
13  *   documentation and/or other materials provided with the distribution.
14  *
15  * Neither the name of Sun Microsystems, Inc. or the names of
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * This software is provided "AS IS," without a warranty of any kind. ALL
20  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
23  * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
24  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
25  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
26  * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
27  * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
28  * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
29  * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
30  * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * You acknowledge that this software is not designed or intended for use
33  * in the design, construction, operation or maintenance of any nuclear
34  * facility.
35  *
36  * Sun gratefully acknowledges that this software was originally authored
37  * and developed by Kenneth Bradley Russell and Christopher John Kline.
38  */
39 
40 package com.sun.gluegen.cgram.types;
41 
42 import java.util.*;
43 
44 /** Describes a function type, used to model both function
45     declarations and (via PointerType) function pointers. */
46 
47 public class FunctionType extends Type {
48   private Type returnType;
49   private ArrayList argumentTypes;
50   private ArrayList argumentNames;
51 
FunctionType(String name, SizeThunk size, Type returnType, int cvAttributes)52   public FunctionType(String name, SizeThunk size, Type returnType, int cvAttributes) {
53     super(name, size, cvAttributes);
54     this.returnType = returnType;
55   }
56 
equals(Object arg)57   public boolean equals(Object arg) {
58     if (arg == this) return true;
59     if (arg == null || (!(arg instanceof FunctionType))) {
60       return false;
61     }
62     FunctionType t = (FunctionType) arg;
63     return (super.equals(arg) &&
64             returnType.equals(t.returnType) &&
65             listsEqual(argumentTypes, t.argumentTypes));
66   }
67 
asFunction()68   public FunctionType asFunction()   { return this; }
69 
70   /** Returns the return type of this function. */
getReturnType()71   public Type getReturnType()        { return returnType; }
72 
getNumArguments()73   public int  getNumArguments()      { return ((argumentTypes == null) ? 0 : argumentTypes.size()); }
74 
75   /** Returns the name of the <i>i</i>th argument. May return null if
76       no argument names were available during parsing. */
getArgumentName(int i)77   public String getArgumentName(int i) {
78     return (String) argumentNames.get(i);
79   }
80 
81   /** Returns the type of the <i>i</i>th argument. */
getArgumentType(int i)82   public Type getArgumentType(int i) {
83     return (Type) argumentTypes.get(i);
84   }
85 
86   /** Add an argument's name and type. Use null for unknown argument
87       names. */
addArgument(Type argumentType, String argumentName)88   public void addArgument(Type argumentType, String argumentName) {
89     if (argumentTypes == null) {
90       argumentTypes = new ArrayList();
91       argumentNames = new ArrayList();
92     }
93     argumentTypes.add(argumentType);
94     argumentNames.add(argumentName);
95   }
96 
setArgumentName(int i, String name)97   public void setArgumentName(int i, String name)
98   {
99     argumentNames.set(i,name);
100   }
101 
toString()102   public String toString() {
103     return toString(null);
104   }
105 
toString(String functionName)106   public String toString(String functionName) {
107     return toString(functionName, false);
108   }
109 
toString(String functionName, boolean emitNativeTag)110   public String toString(String functionName, boolean emitNativeTag) {
111     return toString(functionName, emitNativeTag, false);
112   }
113 
toString(String functionName, boolean emitNativeTag, boolean isPointer)114   String toString(String functionName, boolean emitNativeTag, boolean isPointer) {
115     StringBuffer res = new StringBuffer();
116     res.append(getReturnType());
117     res.append(" ");
118     if (isPointer) {
119       res.append("(*");
120     }
121     if (functionName != null) {
122       if (emitNativeTag) {
123         // Emit @native tag for javadoc purposes
124         res.append("{@native ");
125       }
126       res.append(functionName);
127       if (emitNativeTag) {
128         res.append("}");
129       }
130     }
131     if (isPointer) {
132       res.append(")");
133     }
134     res.append("(");
135     int n = getNumArguments();
136     for (int i = 0; i < n; i++) {
137       Type t = getArgumentType(i);
138       if (t.isFunctionPointer()) {
139         FunctionType ft = t.asPointer().getTargetType().asFunction();
140         res.append(ft.toString(getArgumentName(i), false, true));
141       } else if (t.isArray()) {
142         res.append(t.asArray().toString(getArgumentName(i)));
143       } else {
144         res.append(t);
145         String argumentName = getArgumentName(i);
146         if (argumentName != null) {
147           res.append(" ");
148           res.append(argumentName);
149         }
150       }
151       if (i < n - 1) {
152         res.append(", ");
153       }
154     }
155     res.append(")");
156     if (!isPointer) {
157       res.append(";");
158     }
159     return res.toString();
160   }
161 
visit(TypeVisitor arg)162   public void visit(TypeVisitor arg) {
163     super.visit(arg);
164     returnType.visit(arg);
165     int n = getNumArguments();
166     for (int i = 0; i < n; i++) {
167       getArgumentType(i).visit(arg);
168     }
169   }
170 
newCVVariant(int cvAttributes)171   Type newCVVariant(int cvAttributes) {
172     // Functions don't have const/volatile attributes
173     return this;
174   }
175 }
176