Commit 268e31d5 authored by Jürg Billeter's avatar Jürg Billeter

Add initial support for POSIX profile

Add --profile command-line option.

Code compiled with valac --profile posix will not depend on GLib or
GObject. However, many language features are currently not supported
with the POSIX profile.
parent 4d3bcdac
......@@ -64,6 +64,7 @@ class Vala.Compiler {
static string[] defines;
static bool quiet_mode;
static bool verbose_mode;
static string profile;
private CodeContext context;
......@@ -93,6 +94,7 @@ class Vala.Compiler {
{ "Xcc", 'X', 0, OptionArg.STRING_ARRAY, ref cc_options, "Pass OPTION to the C compiler", "OPTION..." },
{ "dump-tree", 0, 0, OptionArg.FILENAME, ref dump_tree, "Write code tree to FILE", "FILE" },
{ "save-temps", 0, 0, OptionArg.NONE, ref save_temps, "Keep temporary files", null },
{ "profile", 0, 0, OptionArg.STRING, ref profile, "Use the given profile instead of the default", "PROFILE" },
{ "quiet", 'q', 0, OptionArg.NONE, ref quiet_mode, "Do not print messages to the console", null },
{ "verbose", 'v', 0, OptionArg.NONE, ref verbose_mode, "Print additional messages to the console", null },
{ "target-glib", 0, 0, OptionArg.STRING, ref target_glib, "Target version of glib for code generation", "MAJOR.MINOR" },
......@@ -197,6 +199,16 @@ class Vala.Compiler {
context.debug = debug;
context.thread = thread;
context.save_temps = save_temps;
if (profile == "posix") {
context.profile = Profile.POSIX;
context.add_define ("POSIX");
} else if (profile == "gobject-2.0" || profile == "gobject" || profile == null) {
// default profile
context.profile = Profile.GOBJECT;
context.add_define ("GOBJECT");
} else {
Report.error (null, "Unknown profile %s".printf (profile));
}
if (defines != null) {
foreach (string define in defines) {
......@@ -204,28 +216,35 @@ class Vala.Compiler {
}
}
int glib_major = 2;
int glib_minor = 12;
if (target_glib != null && target_glib.scanf ("%d.%d", out glib_major, out glib_minor) != 2) {
Report.error (null, "Invalid format for --target-glib");
}
if (context.profile == Profile.POSIX) {
/* default package */
if (!add_package (context, "posix")) {
Report.error (null, "posix not found in specified Vala API directories");
}
} else if (context.profile == Profile.GOBJECT) {
int glib_major = 2;
int glib_minor = 12;
if (target_glib != null && target_glib.scanf ("%d.%d", out glib_major, out glib_minor) != 2) {
Report.error (null, "Invalid format for --target-glib");
}
context.target_glib_major = glib_major;
context.target_glib_minor = glib_minor;
if (context.target_glib_major != 2) {
Report.error (null, "This version of valac only supports GLib 2");
}
context.target_glib_major = glib_major;
context.target_glib_minor = glib_minor;
if (context.target_glib_major != 2) {
Report.error (null, "This version of valac only supports GLib 2");
/* default packages */
if (!add_package (context, "glib-2.0")) {
Report.error (null, "glib-2.0 not found in specified Vala API directories");
}
if (!add_package (context, "gobject-2.0")) {
Report.error (null, "gobject-2.0 not found in specified Vala API directories");
}
}
context.codegen = new CCodeGenerator ();
/* default packages */
if (!add_package (context, "glib-2.0")) {
Report.error (null, "glib-2.0 not found in specified Vala API directories");
}
if (!add_package (context, "gobject-2.0")) {
Report.error (null, "gobject-2.0 not found in specified Vala API directories");
}
if (packages != null) {
foreach (string package in packages) {
if (!add_package (context, package)) {
......@@ -245,8 +264,13 @@ class Vala.Compiler {
if (source.has_suffix (".vala") || source.has_suffix (".gs")) {
var source_file = new SourceFile (context, rpath);
// import the GLib namespace by default (namespace of backend-specific standard library)
source_file.add_using_directive (new UsingDirective (new UnresolvedSymbol (null, "GLib", null)));
if (context.profile == Profile.POSIX) {
// import the Posix namespace by default (namespace of backend-specific standard library)
source_file.add_using_directive (new UsingDirective (new UnresolvedSymbol (null, "Posix", null)));
} else if (context.profile == Profile.GOBJECT) {
// import the GLib namespace by default (namespace of backend-specific standard library)
source_file.add_using_directive (new UsingDirective (new UnresolvedSymbol (null, "GLib", null)));
}
context.add_source_file (source_file);
} else if (source.has_suffix (".vapi")) {
......@@ -328,18 +352,18 @@ class Vala.Compiler {
interface_writer.write_file (context, vapi_filename);
if (context.profile == Profile.GOBJECT) {
var gir_writer = new GIRWriter ();
string gir_filename = "%s.gir".printf (library);
var gir_writer = new GIRWriter ();
string gir_filename = "%s.gir".printf (library);
// put .gir file in current directory unless -d has been explicitly specified
if (directory != null && !Path.is_absolute (gir_filename)) {
gir_filename = "%s%c%s".printf (context.directory, Path.DIR_SEPARATOR, gir_filename);
}
// put .gir file in current directory unless -d has been explicitly specified
if (directory != null && !Path.is_absolute (gir_filename)) {
gir_filename = "%s%c%s".printf (context.directory, Path.DIR_SEPARATOR, gir_filename);
gir_writer.write_file (context, gir_filename);
}
gir_writer.write_file (context, gir_filename);
library = null;
}
if (internal_vapi_filename != null) {
......
......@@ -84,7 +84,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
public DataType bool_type;
public DataType char_type;
public DataType uchar_type;
public DataType unichar_type;
public DataType? unichar_type;
public DataType short_type;
public DataType ushort_type;
public DataType int_type;
......@@ -215,7 +215,6 @@ internal class Vala.CCodeBaseModule : CCodeModule {
bool_type = new BooleanType ((Struct) root_symbol.scope.lookup ("bool"));
char_type = new IntegerType ((Struct) root_symbol.scope.lookup ("char"));
uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar"));
unichar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("unichar"));
short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short"));
ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort"));
int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int"));
......@@ -234,38 +233,45 @@ internal class Vala.CCodeBaseModule : CCodeModule {
double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double"));
string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string"));
var glib_ns = root_symbol.scope.lookup ("GLib");
gtype_type = (TypeSymbol) glib_ns.scope.lookup ("Type");
gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object");
gerror_type = new ErrorType (null, null);
glist_type = (Class) glib_ns.scope.lookup ("List");
gslist_type = (Class) glib_ns.scope.lookup ("SList");
gstringbuilder_type = (TypeSymbol) glib_ns.scope.lookup ("StringBuilder");
garray_type = (TypeSymbol) glib_ns.scope.lookup ("Array");
gbytearray_type = (TypeSymbol) glib_ns.scope.lookup ("ByteArray");
gptrarray_type = (TypeSymbol) glib_ns.scope.lookup ("PtrArray");
gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark"));
gvalue_type = (Struct) glib_ns.scope.lookup ("Value");
mutex_type = (Struct) glib_ns.scope.lookup ("StaticRecMutex");
type_module_type = (TypeSymbol) glib_ns.scope.lookup ("TypeModule");
if (context.module_init_method != null) {
module_init_fragment = new CCodeFragment ();
foreach (FormalParameter parameter in context.module_init_method.get_parameters ()) {
if (parameter.parameter_type.data_type == type_module_type) {
in_plugin = true;
module_init_param_name = parameter.name;
break;
var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar");
if (unichar_struct != null) {
unichar_type = new IntegerType (unichar_struct);
}
if (context.profile == Profile.GOBJECT) {
var glib_ns = root_symbol.scope.lookup ("GLib");
gtype_type = (TypeSymbol) glib_ns.scope.lookup ("Type");
gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object");
gerror_type = new ErrorType (null, null);
glist_type = (Class) glib_ns.scope.lookup ("List");
gslist_type = (Class) glib_ns.scope.lookup ("SList");
gstringbuilder_type = (TypeSymbol) glib_ns.scope.lookup ("StringBuilder");
garray_type = (TypeSymbol) glib_ns.scope.lookup ("Array");
gbytearray_type = (TypeSymbol) glib_ns.scope.lookup ("ByteArray");
gptrarray_type = (TypeSymbol) glib_ns.scope.lookup ("PtrArray");
gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark"));
gvalue_type = (Struct) glib_ns.scope.lookup ("Value");
mutex_type = (Struct) glib_ns.scope.lookup ("StaticRecMutex");
type_module_type = (TypeSymbol) glib_ns.scope.lookup ("TypeModule");
if (context.module_init_method != null) {
module_init_fragment = new CCodeFragment ();
foreach (FormalParameter parameter in context.module_init_method.get_parameters ()) {
if (parameter.parameter_type.data_type == type_module_type) {
in_plugin = true;
module_init_param_name = parameter.name;
break;
}
}
}
}
var dbus_ns = root_symbol.scope.lookup ("DBus");
if (dbus_ns != null) {
dbus_object_type = (TypeSymbol) dbus_ns.scope.lookup ("Object");
var dbus_ns = root_symbol.scope.lookup ("DBus");
if (dbus_ns != null) {
dbus_object_type = (TypeSymbol) dbus_ns.scope.lookup ("Object");
}
}
header_declarations = new CCodeDeclarationSpace ();
......@@ -292,8 +298,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
once.append (new CCodeNewline ());
once.append (header_declarations.include_directives);
once.append (new CCodeNewline ());
once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
once.append (new CCodeNewline ());
if (context.profile == Profile.GOBJECT) {
once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
once.append (new CCodeNewline ());
}
once.append (new CCodeNewline ());
once.append (header_declarations.type_declaration);
once.append (new CCodeNewline ());
......@@ -303,8 +313,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
once.append (new CCodeNewline ());
once.append (header_declarations.constant_declaration);
once.append (new CCodeNewline ());
once.append (new CCodeIdentifier ("G_END_DECLS"));
once.append (new CCodeNewline ());
if (context.profile == Profile.GOBJECT) {
once.append (new CCodeIdentifier ("G_END_DECLS"));
once.append (new CCodeNewline ());
}
once.append (new CCodeNewline ());
once.write (writer);
writer.close ();
......@@ -323,8 +337,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
once.append (new CCodeNewline ());
once.append (internal_header_declarations.include_directives);
once.append (new CCodeNewline ());
once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
once.append (new CCodeNewline ());
if (context.profile == Profile.GOBJECT) {
once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
once.append (new CCodeNewline ());
}
once.append (new CCodeNewline ());
once.append (internal_header_declarations.type_declaration);
once.append (new CCodeNewline ());
......@@ -334,8 +352,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
once.append (new CCodeNewline ());
once.append (internal_header_declarations.constant_declaration);
once.append (new CCodeNewline ());
once.append (new CCodeIdentifier ("G_END_DECLS"));
once.append (new CCodeNewline ());
if (context.profile == Profile.GOBJECT) {
once.append (new CCodeIdentifier ("G_END_DECLS"));
once.append (new CCodeNewline ());
}
once.append (new CCodeNewline ());
once.write (writer);
writer.close ();
......@@ -418,10 +440,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
wrappers = new HashSet<string> (str_hash, str_equal);
generated_external_symbols = new HashSet<Symbol> ();
header_declarations.add_include ("glib.h");
internal_header_declarations.add_include ("glib.h");
source_declarations.add_include ("glib.h");
source_declarations.add_include ("glib-object.h");
if (context.profile == Profile.GOBJECT) {
header_declarations.add_include ("glib.h");
internal_header_declarations.add_include ("glib.h");
source_declarations.add_include ("glib.h");
source_declarations.add_include ("glib-object.h");
}
source_file.accept_children (codegen);
......@@ -1086,9 +1110,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
} else if (type.data_type is Enum) {
var en = (Enum) type.data_type;
generate_enum_declaration (en, decl_space);
} else if (type is StructValueType) {
var struct_type = (StructValueType) type;
generate_struct_declaration ((Struct) struct_type.type_symbol, decl_space);
} else if (type is ValueType) {
var value_type = (ValueType) type;
generate_struct_declaration ((Struct) value_type.type_symbol, decl_space);
} else if (type is ArrayType) {
var array_type = (ArrayType) type;
generate_type_declaration (array_type.element_type, decl_space);
......@@ -2445,7 +2469,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
public override void visit_boolean_literal (BooleanLiteral expr) {
expr.ccodenode = new CCodeConstant (expr.value ? "TRUE" : "FALSE");
if (context.profile == Profile.GOBJECT) {
expr.ccodenode = new CCodeConstant (expr.value ? "TRUE" : "FALSE");
} else {
source_declarations.add_include ("stdbool.h");
expr.ccodenode = new CCodeConstant (expr.value ? "true" : "false");
}
}
public override void visit_character_literal (CharacterLiteral expr) {
......@@ -2482,6 +2511,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
public override void visit_null_literal (NullLiteral expr) {
if (context.profile != Profile.GOBJECT) {
source_declarations.add_include ("stddef.h");
}
expr.ccodenode = new CCodeConstant ("NULL");
}
......@@ -2758,7 +2790,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
return true;
} else if (st == char_type.data_type) {
return true;
} else if (st == unichar_type.data_type) {
} else if (unichar_type != null && st == unichar_type.data_type) {
return true;
} else if (st == short_type.data_type) {
return true;
......@@ -2827,6 +2859,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
public virtual void generate_class_declaration (Class cl, CCodeDeclarationSpace decl_space) {
if (decl_space.add_symbol_declaration (cl, cl.get_cname ())) {
return;
}
}
public virtual void generate_interface_declaration (Interface iface, CCodeDeclarationSpace decl_space) {
......@@ -3826,6 +3861,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
return node.ccodenode;
}
public override void visit_class (Class cl) {
}
}
// vim:sw=8 noet
......@@ -50,29 +50,38 @@ public class Vala.CCodeCompiler {
*/
[NoArrayLength]
public void compile (CodeContext context, string? cc_command, string[] cc_options) {
bool use_pkgconfig = false;
string pc = "pkg-config --cflags";
if (!context.compile_only) {
pc += " --libs";
}
pc += " gobject-2.0";
if (context.thread) {
pc += " gthread-2.0";
if (context.profile == Profile.GOBJECT) {
use_pkgconfig = true;
pc += " gobject-2.0";
if (context.thread) {
pc += " gthread-2.0";
}
}
foreach (string pkg in context.get_packages ()) {
if (package_exists (pkg))
if (package_exists (pkg)) {
use_pkgconfig = true;
pc += " " + pkg;
}
}
string pkgflags;
int exit_status;
try {
Process.spawn_command_line_sync (pc, out pkgflags, null, out exit_status);
if (exit_status != 0) {
Report.error (null, "pkg-config exited with status %d".printf (exit_status));
string pkgflags = "";
if (use_pkgconfig) {
try {
int exit_status;
Process.spawn_command_line_sync (pc, out pkgflags, null, out exit_status);
if (exit_status != 0) {
Report.error (null, "pkg-config exited with status %d".printf (exit_status));
return;
}
} catch (SpawnError e) {
Report.error (null, e.message);
return;
}
} catch (SpawnError e) {
Report.error (null, e.message);
return;
}
// TODO compile the C code files in parallel
......@@ -118,6 +127,7 @@ public class Vala.CCodeCompiler {
}
try {
int exit_status;
Process.spawn_command_line_sync (cmdline, null, null, out exit_status);
if (exit_status != 0) {
Report.error (null, "cc exited with status %d".printf (exit_status));
......
......@@ -32,28 +32,45 @@ public class Vala.CCodeGenerator : CodeGenerator {
public CCodeModule head;
public CCodeGenerator () {
/* included by inheritance
head = new CCodeBaseModule (this, head);
head = new CCodeStructModule (this, head);
head = new CCodeMethodModule (this, head);
head = new CCodeControlFlowModule (this, head);
head = new CCodeMemberAccessModule (this, head);
head = new CCodeAssignmentModule (this, head);
head = new CCodeMethodCallModule (this, head);
head = new CCodeArrayModule (this, head);
head = new CCodeDelegateModule (this, head);
head = new GErrorModule (this, head);
head = new GTypeModule (this, head);
head = new GObjectModule (this, head);
head = new GSignalModule (this, head);
head = new GAsyncModule (this, head);
head = new DBusClientModule (this, head);
*/
head = new DBusServerModule (this, head);
}
public override void emit (CodeContext context) {
if (context.profile == Profile.GOBJECT) {
/* included by inheritance
head = new CCodeBaseModule (this, head);
head = new CCodeStructModule (this, head);
head = new CCodeMethodModule (this, head);
head = new CCodeControlFlowModule (this, head);
head = new CCodeMemberAccessModule (this, head);
head = new CCodeAssignmentModule (this, head);
head = new CCodeMethodCallModule (this, head);
head = new CCodeArrayModule (this, head);
head = new CCodeDelegateModule (this, head);
head = new GErrorModule (this, head);
head = new GTypeModule (this, head);
head = new GObjectModule (this, head);
head = new GSignalModule (this, head);
head = new GAsyncModule (this, head);
head = new DBusClientModule (this, head);
*/
head = new DBusServerModule (this, head);
} else {
/* included by inheritance
head = new CCodeBaseModule (this, head);
head = new CCodeStructModule (this, head);
head = new CCodeMethodModule (this, head);
head = new CCodeControlFlowModule (this, head);
head = new CCodeMemberAccessModule (this, head);
head = new CCodeAssignmentModule (this, head);
head = new CCodeMethodCallModule (this, head);
head = new CCodeArrayModule (this, head);
*/
head = new CCodeDelegateModule (this, head);
}
head.emit (context);
head = null;
}
public override void visit_source_file (SourceFile source_file) {
......
......@@ -218,7 +218,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
if (cl != null && !cl.is_compact) {
if (cl.base_class == null) {
in_fundamental_creation_method = true;
} else if (cl.is_subtype_of (gobject_type)) {
} else if (gobject_type != null && cl.is_subtype_of (gobject_type)) {
in_gobject_creation_method = true;
}
}
......@@ -603,16 +603,18 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
cmain.add_parameter (new CCodeFormalParameter ("argv", "char **"));
var main_block = new CCodeBlock ();
if (context.thread) {
var thread_init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_thread_init"));
thread_init_call.line = cmain.line;
thread_init_call.add_argument (new CCodeConstant ("NULL"));
main_block.add_statement (new CCodeExpressionStatement (thread_init_call));
}
if (context.profile == Profile.GOBJECT) {
if (context.thread) {
var thread_init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_thread_init"));
thread_init_call.line = cmain.line;
thread_init_call.add_argument (new CCodeConstant ("NULL"));
main_block.add_statement (new CCodeExpressionStatement (thread_init_call));
}
var type_init_call = new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_type_init")));
type_init_call.line = cmain.line;
main_block.add_statement (type_init_call);
var type_init_call = new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_type_init")));
type_init_call.line = cmain.line;
main_block.add_statement (type_init_call);
}
var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name));
if (m.get_parameters ().size == 1) {
......@@ -944,7 +946,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
public override void visit_creation_method (CreationMethod m) {
bool visible = !m.is_private_symbol ();
if (m.body != null && current_type_symbol is Class && current_class.is_subtype_of (gobject_type)) {
if (m.body != null && current_type_symbol is Class
&& gobject_type != null && current_class.is_subtype_of (gobject_type)) {
int n_params = 0;
foreach (Statement stmt in m.body.get_statements ()) {
var expr_stmt = stmt as ExpressionStatement;
......@@ -995,7 +998,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
source_type_member_definition.append (vfunc);
}
if (current_type_symbol is Class && current_class.is_subtype_of (gobject_type)
if (current_type_symbol is Class && gobject_type != null && current_class.is_subtype_of (gobject_type)
&& (((CreationMethod) m).n_construction_params > 0 || current_class.get_type_parameters ().size > 0)) {
var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, new CCodeIdentifier ("__params_it"), new CCodeIdentifier ("__params"));
var cdofreeparam = new CCodeBlock ();
......
......@@ -34,6 +34,22 @@ internal class Vala.CCodeStructModule : CCodeBaseModule {
return;
}
if (st.is_boolean_type ()) {
// typedef for boolean types
decl_space.add_include ("stdbool.h");
st.set_cname ("bool");
return;
} else if (st.is_integer_type ()) {
// typedef for integral types
decl_space.add_include ("stdint.h");
st.set_cname ("%sint%d_t".printf (st.signed ? "" : "u", st.width));
return;
} else if (st.is_floating_type ()) {
// typedef for floating types
st.set_cname (st.width == 64 ? "double" : "float");
return;
}
if (st.has_type_id) {
decl_space.add_type_declaration (new CCodeNewline ());
var macro = "(%s_get_type ())".printf (st.get_lower_case_cname (null));
......@@ -135,13 +151,15 @@ internal class Vala.CCodeStructModule : CCodeBaseModule {
st.accept_children (codegen);
if (st.is_disposable ()) {
add_struct_copy_function (st);
add_struct_destroy_function (st);
}
if (!st.is_boolean_type () && !st.is_integer_type () && !st.is_floating_type ()) {
if (st.is_disposable ()) {
add_struct_copy_function (st);
add_struct_destroy_function (st);
}
add_struct_dup_function (st);
add_struct_free_function (st);
add_struct_dup_function (st);
add_struct_free_function (st);
}
current_type_symbol = old_type_symbol;
instance_finalize_fragment = old_instance_finalize_fragment;
......
......@@ -107,6 +107,7 @@ libvalacore_la_VALASOURCES = \
valapointerindirection.vala \
valapointertype.vala \
valapostfixexpression.vala \
valaprofile.vala \
valapropertyaccessor.vala \
valaproperty.vala \
valarealliteral.vala \
......
......@@ -130,6 +130,8 @@ public class Vala.CodeContext {
*/
public bool save_temps { get; set; }
public Profile profile { get; set; }
/**
* Target major version number of glib for code generation.
*/
......
/* valaprofile.vala
*
* Copyright (C) 2009 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author:
* Jürg Billeter <j@bitron.ch>
*/
public enum Vala.Profile {
POSIX,
GOBJECT
}
......@@ -90,15 +90,25 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint"));
long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long"));
ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong"));
size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t"));
ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t"));
int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8"));
unichar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("unichar"));
double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double"));
// TODO: don't require GLib namespace in semantic analyzer
var glib_ns = root_symbol.scope.lookup ("GLib");
if (glib_ns != null) {
var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar");
if (unichar_struct != null) {
unichar_type = new IntegerType (unichar_struct);
}
var size_t_struct = (Struct) root_symbol.scope.lookup ("size_t");
if (size_t_struct != null) {
size_t_type = new IntegerType (size_t_struct);
}
var ssize_t_struct = (Struct) root_symbol.scope.lookup ("ssize_t");
if (ssize_t_struct != null) {
ssize_t_type = new IntegerType (ssize_t_struct);
}
if (context.profile == Profile.GOBJECT) {
var glib_ns = root_symbol.scope.lookup ("GLib");
object_type = (Class) glib_ns.scope.lookup ("Object");
type_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Type"));
......
......@@ -91,6 +91,10 @@ public class Vala.Struct : TypeSymbol {
*/
public bool has_type_id { get; set; default = true; }
public int width { get; set; default = 32; }
public bool signed { get; set; default = true; }
/**
* Creates a new struct.
*
......@@ -412,6 +416,12 @@ public class Vala.Struct : TypeSymbol {
if (a.has_argument ("rank")) {
rank = a.get_integer ("rank");
}
if (a.has_argument ("width")) {
width = a.get_integer ("width");
}
if (a.has_argument ("signed")) {
signed = a.get_bool ("signed");
}
}
private void process_floating_type_attribute (Attribute a) {
......@@ -419,6 +429,9 @@ public class Vala.Struct : TypeSymbol {
if (a.has_argument ("rank")) {
rank = a.get_integer ("rank");
}
if (a.has_argument ("width")) {
width = a.get_integer ("width");
}
}
/**
......@@ -579,7 +592,8 @@ public class Vala.Struct : TypeSymbol {
return true;
}
}
return get_attribute ("SimpleType") != null;
return (boolean_type || integer_type || floating_type
|| get_attribute ("SimpleType") != null);
}
/**
......@@ -718,7 +732,8 @@ public class Vala.Struct : TypeSymbol {
m.check (analyzer);
}
if (!external && !external_package && base_type == null && get_fields ().size == 0) {
if (!external && !external_package && base_type == null && get_fields ().size == 0
&& !is_boolean_type () && !is_integer_type () && !is_floating_type ()) {
error = true;
Report.error (source_reference, "structs cannot be empty");
}
......
......@@ -20,6 +20,126 @@
* Jürg Billeter <j@bitron.ch>