dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] pnet ChangeLog codegen/cg_gen.c codegen/cg_gen....


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] pnet ChangeLog codegen/cg_gen.c codegen/cg_gen....
Date: Sun, 19 Apr 2009 11:43:44 +0000

CVSROOT:        /cvsroot/dotgnu-pnet
Module name:    pnet
Changes by:     Klaus Treichel <ktreichel>      09/04/19 11:43:44

Modified files:
        .              : ChangeLog 
        codegen        : cg_gen.c cg_gen.h cg_output.c Makefile.am 
        cscc/common    : cc_errors.c cc_errors.h cc_main.c 
        cscc/csharp    : cs_attrs.c 
Added files:
        codegen        : cg_errors.c cg_errors.h cg_genattr.c 
                         cg_genattr.h cg_intl.h 

Log message:
        Add first shot of new handling of custom attributes in the compilers.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/ChangeLog?cvsroot=dotgnu-pnet&r1=1.3617&r2=1.3618
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_gen.c?cvsroot=dotgnu-pnet&r1=1.54&r2=1.55
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_gen.h?cvsroot=dotgnu-pnet&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_output.c?cvsroot=dotgnu-pnet&r1=1.26&r2=1.27
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/Makefile.am?cvsroot=dotgnu-pnet&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_errors.c?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_errors.h?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_genattr.c?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_genattr.h?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/codegen/cg_intl.h?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/cscc/common/cc_errors.c?cvsroot=dotgnu-pnet&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pnet/cscc/common/cc_errors.h?cvsroot=dotgnu-pnet&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pnet/cscc/common/cc_main.c?cvsroot=dotgnu-pnet&r1=1.40&r2=1.41
http://cvs.savannah.gnu.org/viewcvs/pnet/cscc/csharp/cs_attrs.c?cvsroot=dotgnu-pnet&r1=1.32&r2=1.33

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ChangeLog,v
retrieving revision 1.3617
retrieving revision 1.3618
diff -u -b -r1.3617 -r1.3618
--- ChangeLog   18 Apr 2009 19:18:18 -0000      1.3617
+++ ChangeLog   19 Apr 2009 11:43:43 -0000      1.3618
@@ -1,3 +1,40 @@
+2009-04-19  Klaus Treichel  <address@hidden>
+
+       * codegen/cg_errors.c, codegen/cg_errors.h: Add codegen functions to
+       handle errors and warnings.
+
+       * codegen/cg_gen.c (ILGenInfoInit): Initialize the new members
+       errFunc and warnFunc of the ILGenInfo structure.
+
+       * codegen/cg_gen.h: Add the new members errFunc and warnFunc to the
+       ILGenInfo structure.
+
+       * codegen/cg_genattr.c, codegen/cg_genattr.h: Add handling of custom
+       attributes.
+
+       * codegen/cg_intl.h: Add include for internationalization.
+
+       * codegen/cg_output.c (ILGenModulesAndAssemblies): Add output of the
+       assembly hash algorithm, version and locale.
+
+       * codegen/Makefile.am: Add the new files cg_errors.c, cg_errors.h,
+       cg_genattr.c, cg_genattr.h and cg_intl.h to the codegen sources.
+
+       * cscc/common/cc_errors.c (CCErrorOnLineV, CCWarningOnLineV): Add
+       versions of the error and warning functions with a va_list as last
+       argument instead of an elypsis for callbacks from codegen.
+       Use the vararg definitions from il_vararg.h instead of defining our own.
+
+       * cscc/common/cc_errors.h (CCErrorOnLineV, CCWarningOnLineV): Add
+       declarations.
+       Use the IL_PRINTF from il_vararg.h instead of defining CC_PRINTF.
+
+       * cscc/common/cc_main.c (InitCodeGen): Set errFunc and warnFunc in the
+       ILGenInfo structure.
+
+       * cscc/csharp/cs_attrs.c: Use the new custom attribute handling in
+       codegen.
+
 2009-04-18  Klaus Treichel  <address@hidden>
 
        * image/class.c (_ILClassExtCreate): Add function to create class

Index: codegen/cg_gen.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/codegen/cg_gen.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -b -r1.54 -r1.55
--- codegen/cg_gen.c    14 Dec 2008 15:20:00 -0000      1.54
+++ codegen/cg_gen.c    19 Apr 2009 11:43:43 -0000      1.55
@@ -147,6 +147,8 @@
 #endif /* IL_VERSION_MAJOR > 1 */
        info->gotoPtrLabel = ILLabel_Undefined;
        info->accessCheck = ILClassAccessible;
+       info->errFunc = 0;
+       info->warnFunc = 0;
        if(useBuiltinLibrary)
        {
                ILGenMakeLibrary(info);

Index: codegen/cg_gen.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/codegen/cg_gen.h,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- codegen/cg_gen.h    16 Apr 2009 15:34:54 -0000      1.53
+++ codegen/cg_gen.h    19 Apr 2009 11:43:43 -0000      1.54
@@ -21,7 +21,9 @@
 #ifndef        _CODEGEN_CG_GEN_H
 #define        _CODEGEN_CG_GEN_H
 
+#include "il_varargs.h"
 #include "il_profile.h"
+#include "il_utils.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -91,6 +93,12 @@
 typedef int (*ILClassAccessCheck)(ILClass *info, ILClass *scope);
 
 /*
+ * Error/Warning handling function
+ */
+typedef void (*ILErrorFunc)(const char *filename, unsigned long linenum,
+                                                       const char *format, 
IL_VA_LIST va);
+
+/*
  * Structure of the code generation context.
  */
 struct _tagILGenInfo
@@ -160,6 +168,8 @@
 #endif /* IL_VERSION_MAJOR > 1 */
        ILLabel                 gotoPtrLabel;           /* Label for "goto *" 
operations */
        ILClassAccessCheck accessCheck;         /* Function for checking access 
permissions. */
+       ILErrorFunc             errFunc;                        /* Function to 
print and handle errors */
+       ILErrorFunc             warnFunc;                       /* Function to 
print and handle warnings */
 };
 
 /*

Index: codegen/cg_output.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/codegen/cg_output.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -b -r1.26 -r1.27
--- codegen/cg_output.c 15 Oct 2007 19:31:07 -0000      1.26
+++ codegen/cg_output.c 19 Apr 2009 11:43:44 -0000      1.27
@@ -662,16 +662,33 @@
        while((assem = (ILAssembly *)ILImageNextToken
                                (info->image, IL_META_TOKEN_ASSEMBLY, assem)) 
!= 0)
        {
+               ILInt32 hashAlgorithm;
+               const ILUInt16 *assemblyVersion;
+               const char *locale;
+
                fputs(".assembly ", info->asmOutput);
                ILDumpFlags(info->asmOutput, ILAssembly_Attrs(assem),
                                        ILAssemblyFlags, 0);
                ILDumpIdentifier(info->asmOutput, ILAssembly_Name(assem), 0,
                                                 IL_DUMP_QUOTE_NAMES);
                fputs("\n{\n", info->asmOutput);
-               version = ILAssemblyGetVersion(assem);
-               fprintf(info->asmOutput, "\t.ver %lu:%lu:%lu:%lu\n",
-                               (unsigned long)(version[0]), (unsigned 
long)(version[1]),
-                               (unsigned long)(version[2]), (unsigned 
long)(version[3]));
+               hashAlgorithm = ILAssemblyGetHashAlgorithm(assem);
+               if(hashAlgorithm)
+               {
+                       fprintf(info->asmOutput, "\t.hash algorithm %u\n",
+                                       (unsigned)hashAlgorithm);
+               }
+               locale = ILAssemblyGetLocale(assem);
+               if(locale)
+               {
+                       fprintf(info->asmOutput, "\t.locale \"%s\"\n", locale);
+               }
+               assemblyVersion = ILAssemblyGetVersion(assem);
+               fprintf(info->asmOutput, "\t.ver %u:%u:%u:%u\n",
+                               (unsigned)(assemblyVersion[0]),
+                               (unsigned)(assemblyVersion[1]),
+                               (unsigned)(assemblyVersion[2]),
+                               (unsigned)(assemblyVersion[3]));
                if(info->hasUnsafe)
                {
                        /* Output the "SkipVerification" permissions block */

Index: codegen/Makefile.am
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/codegen/Makefile.am,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- codegen/Makefile.am 6 Feb 2007 20:54:52 -0000       1.13
+++ codegen/Makefile.am 19 Apr 2009 11:43:44 -0000      1.14
@@ -56,9 +56,14 @@
 libILCodeGen_a_SOURCES = cg_coerce.c \
                                                 cg_coerce.h \
                                                 cg_defs.h \
+                                                cg_errors.c \
+                                                cg_errors.h \
                                                 cg_gen.c \
                                                 cg_gen.h \
+                                                cg_genattr.c \
+                                                cg_genattr.h \
                                                 cg_interface.c \
+                                                cg_intl.h \
                                                 cg_library.c \
                                                 cg_nodemap.c \
                                                 cg_nodemap.h \

Index: cscc/common/cc_errors.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/cscc/common/cc_errors.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- cscc/common/cc_errors.c     1 Jun 2007 11:08:51 -0000       1.4
+++ cscc/common/cc_errors.c     19 Apr 2009 11:43:44 -0000      1.5
@@ -20,26 +20,6 @@
 
 #include "cc_errors.h"
 #include "cc_options.h"
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#define        VA_LIST                         va_list
-#define        VA_START                        va_list va; va_start(va, format)
-#define        VA_END                          va_end(va)
-#define        VA_GET_LIST                     va
-#else
-#ifdef HAVE_VARARGS_H
-#include <varargs.h>
-#define        VA_LIST                         va_list
-#define        VA_START                        va_list va; va_start(va)
-#define        VA_END                          va_end(va)
-#define        VA_GET_LIST                     va
-#else
-#define        VA_LIST                         int
-#define        VA_START
-#define        VA_END
-#define        VA_GET_LIST                     0
-#endif
-#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -52,7 +32,7 @@
  * Print an error or warning message to stderr.
  */
 static void PrintMessage(const char *filename, unsigned long linenum, int 
warning,
-                                                const char *format, VA_LIST va)
+                                                const char *format, IL_VA_LIST 
va)
 {
        /* Print the filename and line number information */
        if(filename)
@@ -82,18 +62,25 @@
 
 void CCError(const char *format, ...)
 {
-       VA_START;
-       PrintMessage(yycurrfilename(), yycurrlinenum(), 0, format, VA_GET_LIST);
-       VA_END;
+       IL_VA_START(format);
+       PrintMessage(yycurrfilename(), yycurrlinenum(), 0, format, 
IL_VA_GET_LIST);
+       IL_VA_END;
+       CCHaveErrors = 1;
+}
+
+void CCErrorOnLineV(const char *filename, unsigned long linenum,
+                                       const char *format, IL_VA_LIST va)
+{
+       PrintMessage(filename, linenum, 0, format, va);
        CCHaveErrors = 1;
 }
 
 void CCErrorOnLine(const char *filename, unsigned long linenum,
                                   const char *format, ...)
 {
-       VA_START;
-       PrintMessage(filename, linenum, 0, format, VA_GET_LIST);
-       VA_END;
+       IL_VA_START(format);
+       PrintMessage(filename, linenum, 0, format, IL_VA_GET_LIST);
+       IL_VA_END;
        CCHaveErrors = 1;
 }
 
@@ -101,10 +88,10 @@
 {
        if(!inhibit_warnings)
        {
-               VA_START;
+               IL_VA_START(format);
                PrintMessage(yycurrfilename(), yycurrlinenum(), 1,
-                                        format, VA_GET_LIST);
-               VA_END;
+                                        format, IL_VA_GET_LIST);
+               IL_VA_END;
                CCHaveWarnings = 1;
                if(warnings_as_errors)
                {
@@ -162,10 +149,24 @@
 {
        if(WarningEnabled(type))
        {
-               VA_START;
+               IL_VA_START(format);
                PrintMessage(yycurrfilename(), yycurrlinenum(), 1,
-                                        format, VA_GET_LIST);
-               VA_END;
+                                        format, IL_VA_GET_LIST);
+               IL_VA_END;
+               CCHaveWarnings = 1;
+               if(warnings_as_errors)
+               {
+                       CCHaveErrors = 1;
+               }
+       }
+}
+
+void CCWarningOnLineV(const char *filename, unsigned long linenum,
+                                         const char *format, IL_VA_LIST va)
+{
+       if(!inhibit_warnings)
+       {
+               PrintMessage(filename, linenum, 1, format, va);
                CCHaveWarnings = 1;
                if(warnings_as_errors)
                {
@@ -179,9 +180,9 @@
 {
        if(!inhibit_warnings)
        {
-               VA_START;
-               PrintMessage(filename, linenum, 1, format, VA_GET_LIST);
-               VA_END;
+               IL_VA_START(format);
+               PrintMessage(filename, linenum, 1, format, IL_VA_GET_LIST);
+               IL_VA_END;
                CCHaveWarnings = 1;
                if(warnings_as_errors)
                {
@@ -195,9 +196,9 @@
 {
        if(WarningEnabled(type))
        {
-               VA_START;
-               PrintMessage(filename, linenum, 1, format, VA_GET_LIST);
-               VA_END;
+               IL_VA_START(format);
+               PrintMessage(filename, linenum, 1, format, IL_VA_GET_LIST);
+               IL_VA_END;
                CCHaveWarnings = 1;
                if(warnings_as_errors)
                {

Index: cscc/common/cc_errors.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/cscc/common/cc_errors.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- cscc/common/cc_errors.h     5 May 2007 15:56:41 -0000       1.4
+++ cscc/common/cc_errors.h     19 Apr 2009 11:43:44 -0000      1.5
@@ -21,6 +21,7 @@
 #ifndef        _CSCC_CC_ERRORS_H
 #define        _CSCC_CC_ERRORS_H
 
+#include "il_varargs.h"
 #include <codegen/cg_nodes.h>
 #include <cscc/common/cc_intl.h>
 
@@ -29,17 +30,6 @@
 #endif
 
 /*
- * Some gcc magic to make it check for correct printf
- * arguments when using the error reporting functions.
- */
-#if defined(__GNUC__)
-       #define CC_PRINTF(str,arg) \
-               __attribute__((__format__ (__printf__, str, arg)))
-#else
-       #define CC_PRINTF(str,arg)
-#endif
-
-/*
  * Error and warning indicators.
  */
 extern int CCHaveErrors;
@@ -48,30 +38,42 @@
 /*
  * Report an error on the current line.
  */
-void CCError(const char *format, ...) CC_PRINTF(1, 2);
+void CCError(const char *format, ...) IL_PRINTF(1, 2);
 
 /*
  * Report an error on a specific line.
  */
 void CCErrorOnLine(const char *filename, unsigned long linenum,
-                                  const char *format, ...) CC_PRINTF(3, 4);
+                                  const char *format, ...) IL_PRINTF(3, 4);
+
+/*
+ * Same as CCErrorOnLine except it takes an IL_VA_LIST as variable argument.
+ */
+void CCErrorOnLineV(const char *filename, unsigned long linenum,
+                                       const char *format, IL_VA_LIST va);
 
 /*
  * Report a warning on the current line.
  */
-void CCWarning(const char *format, ...) CC_PRINTF(1, 2);
+void CCWarning(const char *format, ...) IL_PRINTF(1, 2);
 
 /*
  * Report a typed warning on the current line.  The warning
  * will only be reported if the "type" is enabled.
  */
-void CCTypedWarning(const char *type, const char *format, ...) CC_PRINTF(2, 3);
+void CCTypedWarning(const char *type, const char *format, ...) IL_PRINTF(2, 3);
 
 /*
  * Report a warning on a specific line.
  */
 void CCWarningOnLine(const char *filename, unsigned long linenum,
-                                    const char *format, ...) CC_PRINTF(3, 4);
+                                    const char *format, ...) IL_PRINTF(3, 4);
+
+/*
+ * Same as CCWarningOnLine except it takes an IL_VAL_LIST as variable argument.
+ */
+void CCWarningOnLineV(const char *filename, unsigned long linenum,
+                                         const char *format, IL_VA_LIST va);
 
 /*
  * Report a typed warning on a specific line.  The warning
@@ -79,7 +81,7 @@
  */
 void CCTypedWarningOnLine(const char *filename, unsigned long linenum,
                                          const char *type, const char *format, 
...)
-                                                 CC_PRINTF(4, 5);
+                                                 IL_PRINTF(4, 5);
 
 /*
  * Report either a warning or an error about unsafe constructs.

Index: cscc/common/cc_main.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/cscc/common/cc_main.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -b -r1.40 -r1.41
--- cscc/common/cc_main.c       3 Aug 2008 21:49:12 -0000       1.40
+++ cscc/common/cc_main.c       19 Apr 2009 11:43:44 -0000      1.41
@@ -523,6 +523,8 @@
                                                                           
"target-assembly-name"),
                                  outfile, useBuiltinLibrary);
        CCCodeGen.debugFlag = debug_flag ? -1 : 0;
+       CCCodeGen.errFunc = CCErrorOnLineV;
+       CCCodeGen.warnFunc = CCWarningOnLineV;
 
        /* Set the default "checked" state */
        if(CCStringListContains(extension_flags, num_extension_flags, 
"checked"))

Index: cscc/csharp/cs_attrs.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/cscc/csharp/cs_attrs.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- cscc/csharp/cs_attrs.c      16 Apr 2009 15:34:54 -0000      1.32
+++ cscc/csharp/cs_attrs.c      19 Apr 2009 11:43:44 -0000      1.33
@@ -19,7 +19,9 @@
  */
 
 #include "cs_internal.h"
+#include <codegen/cg_genattr.h>
 #include <codegen/cg_nodemap.h>
+#include "il_program.h"
 #include "il_serialize.h"
 
 #ifdef __cplusplus
@@ -196,16 +198,19 @@
 /*
  * Get the type that is associated with a field or property.
  */
-static ILType *GetAttrFieldType(ILProgramItem *item)
+static ILType *GetAttrFieldType(ILMember *member)
 {
-       ILField *field = ILProgramItemToField(item);
-       ILProperty *property = ILProgramItemToProperty(item);
+       ILProgramItem *item;
+       ILField *field;
+       ILProperty *property;
        ILMethod *setter;
-       if(field)
+
+       item = ILToProgramItem(member);
+       if((field = ILProgramItemToField(item)) != 0)
        {
                return ILField_Type(field);
        }
-       else if(property)
+       else if((property = ILProgramItemToProperty(item)) != 0)
        {
                setter = ILProperty_Setter(property);
                return ILTypeGetParam(ILMethod_Signature(setter), 1);
@@ -247,196 +252,11 @@
 }
 
 /*
- * Convert a type into a name, formatted for use in attribute values.
- */
-static const char *CSTypeToAttrName(ILGenInfo *info, ILType *type)
-{
-       ILClass *classInfo = ILTypeToClass(info, type);
-       const char *name = ILClass_Name(classInfo);
-       const char *namespace = ILClass_Namespace(classInfo);
-       const char *finalName;
-       if(namespace)
-       {
-               finalName = ILInternAppendedString
-                                       (ILInternAppendedString
-                                               (ILInternString((char 
*)namespace, -1),
-                                                ILInternString((char *)".", 
1)),
-                                        ILInternString((char *)name, 
-1)).string;
-       }
-       else
-       {
-               finalName = name;
-       }
-       if(ILClass_NestedParent(classInfo) != 0)
-       {
-               /* Prepend the name of the enclosing nesting class */
-               const char *parentName = CSTypeToAttrName
-                       (info, 
ILType_FromClass(ILClass_NestedParent(classInfo)));
-               finalName = ILInternAppendedString
-                                       (ILInternAppendedString
-                                               (ILInternString((char 
*)parentName, -1),
-                                                ILInternString((char *)"+", 
1)),
-                                        ILInternString((char *)finalName, 
-1)).string;
-       }
-       return finalName;
-}
-
-/* 
- * write an entry into the serialized stream using the provide paramType and
- * argValue and serialType. 
- */
-
-static void WriteSerializedEntry(ILGenInfo *info,
-                                                                
ILSerializeWriter *writer, 
-                                                                ILType 
*paramType,
-                                                                ILEvalValue 
*argValue,
-                                                                ILType 
*argType,
-                                                                int serialType)
-{      
-       ILType *systemType=ILFindSystemType(info,"Type");
-
-       switch(serialType)
-       {
-               case IL_META_SERIALTYPE_BOOLEAN:
-               case IL_META_SERIALTYPE_I1:
-               case IL_META_SERIALTYPE_U1:
-               case IL_META_SERIALTYPE_I2:
-               case IL_META_SERIALTYPE_U2:
-               case IL_META_SERIALTYPE_CHAR:
-               case IL_META_SERIALTYPE_I4:
-               case IL_META_SERIALTYPE_U4:
-               {
-                       ILSerializeWriterSetInt32(writer, argValue->un.i4Value,
-                                                                         
serialType);
-               }
-               break;
-
-               case IL_META_SERIALTYPE_I8:
-               case IL_META_SERIALTYPE_U8:
-               {
-                       ILSerializeWriterSetInt64(writer, argValue->un.i8Value);
-               }
-               break;
-
-               case IL_META_SERIALTYPE_R4:
-               {
-                       ILSerializeWriterSetFloat32(writer, 
argValue->un.r4Value);
-               }
-               break;
-
-               case IL_META_SERIALTYPE_R8:
-               {
-                       ILSerializeWriterSetFloat64(writer, 
argValue->un.r8Value);
-               }
-               break;
-
-               case IL_META_SERIALTYPE_STRING:
-               {
-                       if(argValue->valueType == ILMachineType_String)
-                       {
-                               ILSerializeWriterSetString(writer, 
argValue->un.strValue.str,
-                                                                               
   argValue->un.strValue.len);
-                       }
-                       else
-                       {
-                               ILSerializeWriterSetString(writer, 0, 0);
-                       }
-               }
-               break;
-
-               case IL_META_SERIALTYPE_TYPE:
-               {
-                       const char *name = CSTypeToAttrName
-                               (info, (ILType *)(argValue->un.strValue.str));
-                       ILSerializeWriterSetString(writer, name, strlen(name));
-               }
-               break;
-
-               case IL_META_SERIALTYPE_VARIANT:
-               {
-                       /* Note : We assume the values are castable and
-                        * do not provide any checks here */
-                       if(ILType_IsPrimitive(argType))
-                       {
-                               switch(argValue->valueType)
-                               {       
-                                       case ILMachineType_Boolean:
-                                       case ILMachineType_Int8:
-                                       case ILMachineType_UInt8:
-                                       case ILMachineType_Int16:
-                                       case ILMachineType_UInt16:
-                                       case ILMachineType_Char:
-                                       case ILMachineType_Int32:
-                                       case ILMachineType_UInt32:
-                                       case ILMachineType_Int64:
-                                       case ILMachineType_UInt64:
-                                       case ILMachineType_Float32:
-                                       case ILMachineType_Float64:
-                                       case ILMachineType_Decimal:
-                                       {
-                                               
serialType=ILSerializeGetType(argType);
-                                               
-                                               
ILSerializeWriterSetBoxedPrefix(writer, 
-                                                                               
                                   serialType);
-
-                                               WriteSerializedEntry(info, 
writer, paramType, 
-                                                                               
         argValue, argType, serialType);
-                                       }
-                                       break;
-                                       
-                                       case ILMachineType_String:
-                                       {
-                                               /* TODO */
-                                       }
-                                       break;
-                                       
-                                       default:
-                                       {
-                                       }
-                                       break;
-                               }
-                       }
-                       else if(ILTypeIdentical(argType, systemType))
-                       { 
-                               ILSerializeWriterSetBoxedPrefix(writer,
-                                                                               
IL_META_SERIALTYPE_TYPE);
-                               
-                               WriteSerializedEntry(info, writer, paramType, 
-                                                                        
argValue, argType,
-                                                                        
IL_META_SERIALTYPE_TYPE);
-                       }
-                       else if(ILTypeIsEnum(argType))
-                       {
-                               const char *name = CSTypeToAttrName(info, 
(ILType *)(argType));
-                               ILSerializeWriterSetBoxedPrefix(writer,
-                                                                               
IL_META_SERIALTYPE_ENUM);
-                               ILSerializeWriterSetString(writer, name, 
strlen(name));
-
-                               serialType=ILSerializeGetType(argType);
-
-                               WriteSerializedEntry(info, writer, paramType,
-                                                                               
argValue, argType,
-                                                                               
serialType);    
-                       }
-               }
-               break;
-
-               default:
-               {
-                       if(ILType_IsArray(paramType))
-                       {
-                               /* TODO: arrays */
-                       }
-               }
-               break;
-       }
-}
-
-/*
  * Process a single attribute in a section.
  */
-static void ProcessAttr(ILGenInfo *info, ILProgramItem *item,
-                                               int target, ILNode_Attribute 
*attr)
+static void ProcessAttr(ILGenInfo *info, CGAttributeInfos *attributeInfos,
+                                               ILProgramItem *item, ILUInt32 
target,
+                                               ILNode_Attribute *attr)
 {
        ILType *type;
        ILClass *classInfo;
@@ -446,10 +266,8 @@
        ILNode_ListIter iter;
        ILNode *arg;
        CSEvalArg *evalArgs;
-       ILEvalValue *evalValues;
-       CSEvalArg *namedArgs;
-       ILEvalValue *namedValues;
-       ILProgramItem **namedFields;
+       CGAttrCtorArg *ctorArgs;
+       CGAttrNamedArg *namedArgs;
        CSSemValue value;
        int haveErrors;
        CSSemValue method;
@@ -459,16 +277,7 @@
        ILMethod *methodInfo;
        ILType *signature;
        ILType *paramType;
-       int allowMultiple;
-       int inherited;
-       ILSerializeWriter *writer = 0;
-       ILEvalValue *argValue;
-       int serialType;
-       const void *blob;
-       unsigned long blobLen;
-       ILAttribute *attribute;
        int skipConst;
-       ILType *argType;
 
        /* Modify the name so as to correctly handle "Attribute" suffixes,
           and then perform semantic analysis on the type */
@@ -493,48 +302,16 @@
                return;
        }
 
-       /* Check that that the attribute can be applied to this kind of target.
-          We use a different algorithm for "AttributeUsageAttribute", to avoid
-          circularities in the semantic analysis network */
-       if(!IsAttributeUsage(classInfo))
-       {
                /* Perform semantic analysis on the attribute type, but only
                   if we aren't trying to apply the attribute to itself */
-               if(IsAttributeTargetDistinct(info,item,classInfo))
-               {
-                       CSSemProgramItem(info, ILToProgramItem(classInfo));
-               }
-
-               /* Get the usage information for the attribute */
-               allowMultiple = 1;
-               inherited = 1;
-       }
-       else
-       {
-               /* We can only use "AttributeUsageAttribute" on classes
-                  that inherit from "System.Attribute" */
-               classInfo = ILProgramItemToClass(item);
-               if(!classInfo)
+       if(!IsAttributeUsage(classInfo))
                {
-                       CCErrorOnLine(yygetfilename(attr), yygetlinenum(attr),
-                    _("`System.AttributeUsageAttribute' may only be used on 
classes"));
-                       return;
-               }
-               if(!ILTypeAssignCompatible(info->image, 
ILClassToType(classInfo),
-                                                                  
ILFindSystemType(info, "Attribute")))
+               if(IsAttributeTargetDistinct(info, item, classInfo))
                {
-                       CCErrorOnLine(yygetfilename(attr), yygetlinenum(attr),
-                                                 _("`%s' does not inherit from 
`System.Attribute'"),
-                                                 
CSTypeToName(ILClassToType(classInfo)));
-                       return;
+                       CSSemProgramItem(info, ILToProgramItem(classInfo));
                }
-               allowMultiple = 0;
-               inherited = 1;
        }
 
-       /* Check the "AllowMultiple" and "Inherited" states of the attribute */
-       /* TODO */
-
        /* Perform semantic analysis on the positional attributes */
        if(attr->args)
        {
@@ -553,8 +330,8 @@
                {
                        CCOutOfMemory();
                }
-               evalValues = (ILEvalValue *)ILMalloc(sizeof(ILEvalValue) * 
numArgs);
-               if(!evalValues)
+               ctorArgs = CGAttrCtorArgAlloc(attributeInfos, numArgs);
+               if(!ctorArgs)
                {
                        CCOutOfMemory();
                }
@@ -584,14 +361,15 @@
                        /* Evaluate the constant value of the argument */
                        if(CSSemIsType(value))
                        {
-                               evalValues[argNum].valueType = 
ILMachineType_Void;
-                               evalValues[argNum].un.oValue = 
CSSemGetType(value);
+                               ctorArgs[argNum].evalValue.valueType = 
ILMachineType_Void;
+                               ctorArgs[argNum].evalValue.un.oValue = 
CSSemGetType(value);
                                evalArgs[argNum].type = ILFindSystemType(info, 
"Type");
                        }
                        else
                        {
                                if(!haveErrors &&
-                                  !ILNode_EvalConst(*(iter.last), info, 
&(evalValues[argNum])))
+                                  !ILNode_EvalConst(*(iter.last), info,
+                                                                        
&(ctorArgs[argNum].evalValue)))
                                {
                                        haveErrors = 1;
                                }
@@ -604,7 +382,7 @@
        else
        {
                evalArgs = 0;
-               evalValues = 0;
+               ctorArgs = 0;
        }
 
        /* Perform semantic analysis on the named arguments */
@@ -619,29 +397,17 @@
        numNamedArgs = ILNode_List_Length(namedArgList);
        if(numNamedArgs)
        {
-               namedArgs = (CSEvalArg *)ILMalloc(sizeof(CSEvalArg) * 
numNamedArgs);
+               namedArgs = CGAttrNamedArgAlloc(attributeInfos, numNamedArgs);
                if(!namedArgs)
                {
                        CCOutOfMemory();
                }
-               namedValues = (ILEvalValue *)ILMalloc
-                       (sizeof(ILEvalValue) * numNamedArgs);
-               if(!namedValues)
-               {
-                       CCOutOfMemory();
-               }
-               namedFields = (ILProgramItem **)ILMalloc
-                       (sizeof(ILProgramItem *) * numNamedArgs);
-               if(!namedFields)
-               {
-                       CCOutOfMemory();
-               }
                ILNode_ListIter_Init(&iter, namedArgList);
                argNum = 0;
                while((arg = ILNode_ListIter_Next(&iter)) != 0)
                {
                        /* Convert the name into a field or property */
-                       if((namedFields[argNum] = LookupAttrField
+                       if((namedArgs[argNum].member = (ILMember 
*)LookupAttrField
                                        (info, type, ((ILNode_NamedArg 
*)arg)->name)) == 0)
                        {
                                CCErrorOnLine
@@ -670,13 +436,12 @@
                        }
                        namedArgs[argNum].node = ((ILNode_NamedArg 
*)arg)->value;
                        namedArgs[argNum].parent = &(((ILNode_NamedArg 
*)arg)->value);
-                       namedArgs[argNum].modifier = ILParamMod_empty;
 
                        /* Evaluate the constant value of the argument */
                        if(CSSemIsType(value))
                        {
-                               namedValues[argNum].valueType = 
ILMachineType_Void;
-                               namedValues[argNum].un.oValue = 
CSSemGetType(value);
+                               namedArgs[argNum].evalValue.valueType = 
ILMachineType_Void;
+                               namedArgs[argNum].evalValue.un.oValue = 
CSSemGetType(value);
                                namedArgs[argNum].type = ILFindSystemType(info, 
"Type");
                                skipConst = 1;
                        }
@@ -684,7 +449,7 @@
                        {
                                if(!haveErrors &&
                                   !ILNode_EvalConst(namedArgs[argNum].node, 
info,
-                                                                        
&(namedValues[argNum])))
+                                                                        
&(namedArgs[argNum].evalValue)))
                                {
                                        haveErrors = 1;
                                }
@@ -697,12 +462,12 @@
                                if(ILCoerce(info, namedArgs[argNum].node,
                                                        
namedArgs[argNum].parent,
                                                        namedArgs[argNum].type,
-                                                       
GetAttrFieldType(namedFields[argNum]),1) &&
+                                                       
GetAttrFieldType(namedArgs[argNum].member),1) &&
                                   (skipConst || ILGenCastConst
-                                               (info, &(namedValues[argNum]),
-                                                namedValues[argNum].valueType,
+                                               (info, 
&(namedArgs[argNum].evalValue),
+                                                
namedArgs[argNum].evalValue.valueType,
                                                 ILTypeToMachineType
-                                                               
(GetAttrFieldType(namedFields[argNum])))))
+                                                               
(GetAttrFieldType(namedArgs[argNum].member)))))
                                {
                                        namedArgs[argNum].node = 
*(namedArgs[argNum].parent);
                                }
@@ -713,7 +478,7 @@
                                                                  "cannot 
coerce from `%s' to `%s'",
                                                                  
CSTypeToName(namedArgs[argNum].type),
                                                                  
CSTypeToName(GetAttrFieldType
-                                                                               
(namedFields[argNum])));
+                                                                               
(namedArgs[argNum].member)));
                                        haveErrors = 1;
                                }
                        }
@@ -725,8 +490,6 @@
        else
        {
                namedArgs = 0;
-               namedValues = 0;
-               namedFields = 0;
        }
 
        /* Bail out if we had errors during analysis of the arguments */
@@ -786,24 +549,18 @@
                }
        }
 
-       /* Import the constructor method into this image */
-       methodInfo = (ILMethod *)ILMemberImport
-                                               (info->image, (ILMember 
*)itemInfo);
-       if(!methodInfo)
-       {
-               CCOutOfMemory();
-       }
-
        /* Coerce the positional arguments to their final types */
+       methodInfo = (ILMethod *)itemInfo;
        signature = ILMethod_Signature(methodInfo);
        haveErrors = 0;
        for(argNum = 0; argNum < numArgs; ++argNum)
        {
                paramType = ILTypeGetParam(signature, argNum + 1);
-               if(evalValues[argNum].valueType != ILMachineType_Void)
+               if(ctorArgs[argNum].evalValue.valueType != ILMachineType_Void)
                {
-                       if(!ILGenCastConst(info, &(evalValues[argNum]),
-                                  
evalValues[argNum].valueType,ILTypeToMachineType(paramType))
+                       if(!ILGenCastConst(info, &(ctorArgs[argNum].evalValue),
+                                                          
ctorArgs[argNum].evalValue.valueType,
+                                                          
ILTypeToMachineType(paramType))
                           && !ILCanCastKind(info, evalArgs[argNum].type,
                                                                paramType, 
IL_CONVERT_STANDARD,0))
                        {
@@ -823,104 +580,30 @@
                                haveErrors = 1;
                        }
                }
+               ctorArgs[argNum].node = evalArgs[argNum].node;
+               ctorArgs[argNum].parent = evalArgs[argNum].parent;
+               ctorArgs[argNum].type = evalArgs[argNum].type;
        }
        if(haveErrors)
        {
                goto cleanup;
        }
 
-       /* Build the serialized attribute value */
-       writer = ILSerializeWriterInit();
-       if(!writer)
-       {
-               CCOutOfMemory();
-       }
-       for(argNum = 0; argNum < numArgs; ++argNum)
-       {
-               paramType = ILTypeGetParam(signature, argNum + 1);
-               argValue = &(evalValues[argNum]);
-               argType = evalArgs[argNum].type;
-               serialType = ILSerializeGetType(paramType);
-               
WriteSerializedEntry(info,writer,paramType,argValue,argType,serialType);
-       }
-       ILSerializeWriterSetNumExtra(writer, numNamedArgs);
-       for(argNum = 0; argNum < numNamedArgs; ++argNum)
-       {
-               argValue = &(namedValues[argNum]);
-               if(argValue->valueType == ILMachineType_Void)
-               {
-                       serialType = IL_META_SERIALTYPE_TYPE;
-                       paramType = NULL;
-               }
-               else
-               {
-                       paramType = ILValueTypeToType(info, 
argValue->valueType);
-                       serialType = ILSerializeGetType(paramType);
-               }
-               if(ILMember_IsField(((ILMember *)(namedFields[argNum]))))
-               {
-                       ILSerializeWriterSetField
-                               (writer, ILMember_Name((ILMember 
*)(namedFields[argNum])),
-                                serialType);
-               }
-               else
-               {
-                       ILSerializeWriterSetProperty
-                               (writer, ILMember_Name((ILMember 
*)(namedFields[argNum])),
-                                serialType);
-               }
-               argType=namedArgs[argNum].type;
-               
WriteSerializedEntry(info,writer,paramType,argValue,argType,serialType);
-       }
-       blob = ILSerializeWriterGetBlob(writer, &blobLen);
-       if(!blob)
-       {
-               CCOutOfMemory();
-       }
-
-       /* Add the attribute value to the program item */
-       attribute = ILAttributeCreate(info->image, 0);
-       if(!attribute)
-       {
-               CCOutOfMemory();
-       }
-       ILAttributeSetType(attribute, ILToProgramItem(methodInfo));
-       if(!ILAttributeSetValue(attribute, blob, blobLen))
-       {
-               CCOutOfMemory();
-       }
-       ILProgramItemAddAttribute(item, attribute);
+       CGAttributeInfosAddAttribute(attributeInfos, (ILNode *)attr, item,
+                                                                methodInfo, 
ctorArgs, numArgs,
+                                                                namedArgs, 
numNamedArgs, target);
 
 cleanup:
        if(evalArgs)
        {
                ILFree(evalArgs);
        }
-       if(evalValues)
-       {
-               ILFree(evalValues);
-       }
-       if(namedArgs)
-       {
-               ILFree(namedArgs);
-       }
-       if(namedValues)
-       {
-               ILFree(namedValues);
-       }
-       if(namedFields)
-       {
-               ILFree(namedFields);
-       }
-       if(writer)
-       {
-               ILSerializeWriterDestroy(writer);
-       }
 }
 
 void CSProcessAttrs(ILGenInfo *info, ILProgramItem *mainItem,
                                        ILNode *attributes, int mainTarget)
 {
+       CGAttributeInfos attributeInfos;
        ILProgramItem *item;
        int target;
        ILNode_ListIter iter;
@@ -938,6 +621,9 @@
                return;
        }
 
+       /* Initislize the attribute infos. */
+       CGAttributeInfosInit(info, &attributeInfos);
+
        /* Scan through the attribute sections */
        ILNode_ListIter_Init(&iter, ((ILNode_AttributeTree *)attributes)
                                                                                
->sections);
@@ -1099,11 +785,18 @@
                        break;
                }
 
+               if(target == 0)
+               {
+                       CCErrorOnLine(yygetfilename(section), 
yygetlinenum(section),
+                                                 _("This is not a valid 
attribute target"));
+                       continue;
+               }
+
                /* Process the attributes in this section */
                ILNode_ListIter_Init(&iter2, section->attrs);
                while((attr = (ILNode_Attribute *)ILNode_ListIter_Next(&iter2)) 
!= 0)
                {
-                       ProcessAttr(info, item, target, attr);
+                       ProcessAttr(info, &attributeInfos, item, target, attr);
                }
 
                /* Convert system library attributes into metadata structures */
@@ -1112,6 +805,11 @@
                        CCOutOfMemory();
                }
        }
+       /* Process tha collected attributes */
+       CGAttributeInfosProcess(&attributeInfos);
+
+       /* Destroy the attribute infos. */
+       CGAttributeInfosDestroy(&attributeInfos);
 }
 
 void CSProcessAttrsForParam(ILGenInfo *info, ILMethod *method,

Index: codegen/cg_errors.c
===================================================================
RCS file: codegen/cg_errors.c
diff -N codegen/cg_errors.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ codegen/cg_errors.c 19 Apr 2009 11:43:43 -0000      1.1
@@ -0,0 +1,147 @@
+/*
+ * cg_errors.c - Error reporting functions for codegen.
+ *
+ * Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "cg_nodes.h"
+#include "cg_intl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Backup function to print an error or warning message to stderr if the
+ * error/warning functions in the gen info block are not set.
+ */
+static void PrintMessage(const char *filename, unsigned long linenum, int 
warning,
+                                                const char *format, IL_VA_LIST 
va)
+{
+       /* Print the filename and line number information */
+       if(filename)
+       {
+               fputs(filename, stderr);
+               putc(':', stderr);
+       }
+       fprintf(stderr, "%lu: ", linenum);
+
+       /* Print the "warning: " prefix if this is a warning */
+       if(warning)
+       {
+               fputs(_("warning: "), stderr);
+       }
+
+       /* Print the message */
+#ifdef HAVE_VFPRINTF
+       vfprintf(stderr, format, va);
+#else
+       /* Shouldn't happen, but at least print the format */
+       fputs(format, stderr);
+#endif
+
+       /* Terminate the line */
+       putc('\n', stderr);
+}
+
+/*
+ * Print an error relative to the given node.
+ * Node must not be 0.
+ */
+void CGErrorForNode(ILGenInfo *info, ILNode *node, const char *format, ...)
+{
+       if(info->errFunc)
+       {
+               IL_VA_START(format);
+               info->errFunc(yygetfilename(node), yygetlinenum(node),
+                                         format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+       else
+       {
+               IL_VA_START(format);
+               PrintMessage(yygetfilename(node), yygetlinenum(node), 0,
+                                        format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+}
+
+/*
+ * Print an error relative to the given location.
+ */
+void CGErrorOnLine(ILGenInfo *info, const char *filename,
+                                  unsigned long linenum, const char *format, 
...)
+{
+       if(info->errFunc)
+       {
+               IL_VA_START(format);
+               info->errFunc(filename, linenum, format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+       else
+       {
+               IL_VA_START(format);
+               PrintMessage(filename, linenum, 0,format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+}
+
+/*
+ * Print a warning relative to the given node.
+ * Node must not be 0.
+ */
+void CGWarningForNode(ILGenInfo *info, ILNode *node, const char *format, ...)
+{
+       if(info->warnFunc)
+       {
+               IL_VA_START(format);
+               info->warnFunc(yygetfilename(node), yygetlinenum(node),
+                                          format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+       else
+       {
+               IL_VA_START(format);
+               PrintMessage(yygetfilename(node), yygetlinenum(node), 1,
+                                        format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+}
+
+/*
+ * Print a warning relative to the given location.
+ */
+void CGWarningOnLine(ILGenInfo *info, const char *filename,
+                                        unsigned long linenum, const char 
*format, ...)
+{
+       if(info->warnFunc)
+       {
+               IL_VA_START(format);
+               info->warnFunc(filename, linenum, format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+       else
+       {
+               IL_VA_START(format);
+               PrintMessage(filename, linenum, 1,format, IL_VA_GET_LIST);
+               IL_VA_END;
+       }
+}
+
+#ifdef __cplusplus
+};
+#endif

Index: codegen/cg_errors.h
===================================================================
RCS file: codegen/cg_errors.h
diff -N codegen/cg_errors.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ codegen/cg_errors.h 19 Apr 2009 11:43:43 -0000      1.1
@@ -0,0 +1,63 @@
+/*
+ * cg_genattrs.h - handle custom attributes.
+ *
+ * Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef        __CODEGEN_CG_ERROR_H__
+#define        __CODEGEN_CG_ERROR_H__
+
+#include "il_varargs.h"
+#include "cg_nodes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Print an error relative to the given node.
+ * Node must not be 0.
+ */
+void CGErrorForNode(ILGenInfo *info, ILNode *node, const char *format, ...)
+                                       IL_PRINTF(3, 4);
+
+/*
+ * Print an error relative to the given location.
+ */
+void CGErrorOnLine(ILGenInfo *info, const char *filename,
+                                  unsigned long linenum, const char *format, 
...)
+                                  IL_PRINTF(4, 5);
+
+/*
+ * Print a warning relative to the given node.
+ * Node must not be 0.
+ */
+void CGWarningForNode(ILGenInfo *info, ILNode *node, const char *format, ...)
+                                         IL_PRINTF(3, 4);
+
+/*
+ * Print a warning relative to the given location.
+ */
+void CGWarningOnLine(ILGenInfo *info, const char *filename,
+                                        unsigned long linenum, const char 
*format, ...)
+                                        IL_PRINTF(4, 5);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* __CODEGEN_CG_ERROR_H__ */

Index: codegen/cg_genattr.c
===================================================================
RCS file: codegen/cg_genattr.c
diff -N codegen/cg_genattr.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ codegen/cg_genattr.c        19 Apr 2009 11:43:43 -0000      1.1
@@ -0,0 +1,2357 @@
+/*
+ * cg_genattr.c - Helper routines for custom attributes.
+ *
+ * Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "cg_genattr.h"
+#include "cg_errors.h"
+#include "cg_coerce.h"
+#include "cg_intl.h"
+#include "il_program.h"
+#include "il_serialize.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _tagCGAttrConvertInfo CGAttrConvertInfo;
+struct _tagCGAttrConvertInfo
+{
+       const char *name;
+       int (*func)(ILGenInfo *info, CGAttributeInfo *attributeInfo);
+
+};
+
+void CGAttributeInfosInit(ILGenInfo *info,
+                                                 CGAttributeInfos 
*attributeInfos)
+{
+       if(attributeInfos == 0)
+       {
+               return;
+       }
+       ILMemStackInit(&(attributeInfos->memstack), 0);
+       attributeInfos->info = info;
+       attributeInfos->attributes = 0;
+}
+
+void CGAttributeInfosDestroy(CGAttributeInfos *attributeInfos)
+{
+       if(attributeInfos == 0)
+       {
+               return;
+       }
+       ILMemStackDestroy(&(attributeInfos->memstack));
+}
+
+CGAttrCtorArg *CGAttrCtorArgAlloc(CGAttributeInfos *attributeInfos,
+                                                                 ILUInt32 
numArgs)
+{
+       CGAttrCtorArg *ctorArg;
+
+
+       if(attributeInfos == 0)
+       {
+               return 0;
+       }
+       if(numArgs == 0)
+       {
+               return 0;
+       }
+       ctorArg = (CGAttrCtorArg *)ILMemStackAllocItem
+                                               (&(attributeInfos->memstack),
+                                                numArgs * 
sizeof(CGAttrCtorArg));
+       if(ctorArg == 0)
+       {
+               ILGenOutOfMemory(attributeInfos->info);
+       }
+       return ctorArg;
+}
+
+CGAttrNamedArg *CGAttrNamedArgAlloc(CGAttributeInfos *attributeInfos,
+                                                                       
ILUInt32 numNamed)
+{
+       CGAttrNamedArg *namedArg;
+
+       if(attributeInfos == 0)
+       {
+               return 0;
+       }
+       if(numNamed == 0)
+       {
+               return 0;
+       }
+       namedArg = (CGAttrNamedArg *)ILMemStackAllocItem
+                                               (&(attributeInfos->memstack),
+                                                numNamed * 
sizeof(CGAttrNamedArg));
+       if(namedArg == 0)
+       {
+               ILGenOutOfMemory(attributeInfos->info);
+       }
+       return namedArg;
+}
+
+/*
+ * Get the target name for an attribute target.
+ */
+static const char *AttributeTargetToName(ILUInt32 target)
+{
+       switch(target)
+       {
+               case IL_ATTRIBUTE_TARGET_ASSEMBLY:
+               {
+                       return "assemblies";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_MODULE:
+               {
+                       return "modules";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_CLASS:
+               {
+                       return "classes";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_STRUCT:
+               {
+                       return "structs";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_ENUM:
+               {
+                       return "enumerations";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_CONSTRUCTOR:
+               {
+                       return "constructors";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_METHOD:
+               {
+                       return "methods";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_PROPERTY:
+               {
+                       return "properties";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_FIELD:
+               {
+                       return "fields";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_EVENT:
+               {
+                       return "events";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_INTERFACE:
+               {
+                       return "interfaces";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_PARAMETER:
+               {
+                       return "parameters";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_DELEGATE:
+               {
+                       return "delegates";
+               }
+               break;
+
+               case IL_ATTRIBUTE_TARGET_RETURNVALUE:
+               {
+                       return "returnvalues";
+               }
+               break;
+
+#if IL_VERSION_MAJOR > 1
+               case IL_ATTRIBUTE_TARGET_GENERICPAR:
+               {
+                       return "generic parameters";
+               }
+#endif
+       }
+       return "Unknown";
+}
+
+/*
+ * Convert a string from UTF-8 to UTF-16.
+ */
+static void *StringToUTF16(const char *str, unsigned long *len, int slen)
+{
+       int posn = 0;
+       unsigned long ch;
+       unsigned long index;
+       char *utf16;
+
+       /* Determine the length of the UTF-16 string in bytes */
+       *len = 0;
+       while(posn < slen)
+       {
+               ch = ILUTF8ReadChar(str, slen, &posn);
+               *len += (unsigned long)ILUTF16WriteCharAsBytes(0, ch);
+       }
+
+       /* Allocate space for the UTF-16 string */
+       utf16 = (char *)ILMalloc(*len * 2);
+       if(!utf16)
+       {
+               return 0;
+       }
+
+       /* Convert the string from UTF-8 to UTF-16 */
+       index = 0;
+       posn = 0;
+       while(posn < slen)
+       {
+               ch = ILUTF8ReadChar(str, slen, &posn);
+               index += (unsigned long)ILUTF16WriteCharAsBytes(utf16 + index, 
ch);
+       }
+       return utf16;
+}
+
+/*
+ * Convert a class into a name used by error messages.
+ */
+static const char *CGClassToName(ILClass *classInfo)
+{
+       const char *name = ILClass_Name(classInfo);
+       const char *namespace = ILClass_Namespace(classInfo);
+       const char *finalName;
+       if(namespace)
+       {
+               finalName = ILInternStringConcat3
+                                               (ILInternString(namespace, -1),
+                                                ILInternString(".", 1),
+                                                ILInternString(name, 
-1)).string;
+       }
+       else
+       {
+               finalName = name;
+       }
+       if(ILClass_NestedParent(classInfo) != 0)
+       {
+               /* Prepend the name of the enclosing nesting class */
+               const char *parentName;
+               parentName = CGClassToName(ILClass_NestedParent(classInfo));
+               finalName = ILInternStringConcat3
+                                               (ILInternString(parentName, -1),
+                                                ILInternString(".", 1),
+                                                ILInternString(finalName, 
-1)).string;
+       }
+       return finalName;
+}
+
+/*
+ * Convert a type into a name, formatted for use in attribute values.
+ */
+static const char *CGTypeToAttrName(ILGenInfo *info, ILType *type)
+{
+       ILClass *classInfo = ILTypeToClass(info, type);
+       const char *name = ILClass_Name(classInfo);
+       const char *namespace = ILClass_Namespace(classInfo);
+       const char *finalName;
+       if(namespace)
+       {
+               finalName = ILInternStringConcat3
+                                               (ILInternString(namespace, -1),
+                                                ILInternString(".", 1),
+                                                ILInternString(name, 
-1)).string;
+       }
+       else
+       {
+               finalName = name;
+       }
+       if(ILClass_NestedParent(classInfo) != 0)
+       {
+               /* Prepend the name of the enclosing nesting class */
+               const char *parentName = CGTypeToAttrName
+                       (info, 
ILType_FromClass(ILClass_NestedParent(classInfo)));
+               finalName = ILInternStringConcat3
+                                               (ILInternString(parentName, -1),
+                                                ILInternString("+", 1),
+                                                ILInternString(finalName, 
-1)).string;
+       }
+       return finalName;
+}
+
+/* 
+ * write an entry into the serialized stream using the provide paramType and
+ * argValue and serialType. 
+ */
+static void WriteSerializedEntry(ILGenInfo *info,
+                                                                
ILSerializeWriter *writer, 
+                                                                ILType 
*paramType,
+                                                                ILEvalValue 
*argValue,
+                                                                ILType 
*argType,
+                                                                int serialType)
+{      
+       ILType *systemType=ILFindSystemType(info,"Type");
+
+       switch(serialType)
+       {
+               case IL_META_SERIALTYPE_BOOLEAN:
+               case IL_META_SERIALTYPE_I1:
+               case IL_META_SERIALTYPE_U1:
+               case IL_META_SERIALTYPE_I2:
+               case IL_META_SERIALTYPE_U2:
+               case IL_META_SERIALTYPE_CHAR:
+               case IL_META_SERIALTYPE_I4:
+               case IL_META_SERIALTYPE_U4:
+               {
+                       ILSerializeWriterSetInt32(writer, argValue->un.i4Value,
+                                                                         
serialType);
+               }
+               break;
+
+               case IL_META_SERIALTYPE_I8:
+               case IL_META_SERIALTYPE_U8:
+               {
+                       ILSerializeWriterSetInt64(writer, argValue->un.i8Value);
+               }
+               break;
+
+               case IL_META_SERIALTYPE_R4:
+               {
+                       ILSerializeWriterSetFloat32(writer, 
argValue->un.r4Value);
+               }
+               break;
+
+               case IL_META_SERIALTYPE_R8:
+               {
+                       ILSerializeWriterSetFloat64(writer, 
argValue->un.r8Value);
+               }
+               break;
+
+               case IL_META_SERIALTYPE_STRING:
+               {
+                       if(argValue->valueType == ILMachineType_String)
+                       {
+                               ILSerializeWriterSetString(writer, 
argValue->un.strValue.str,
+                                                                               
   argValue->un.strValue.len);
+                       }
+                       else
+                       {
+                               ILSerializeWriterSetString(writer, 0, 0);
+                       }
+               }
+               break;
+
+               case IL_META_SERIALTYPE_TYPE:
+               {
+                       const char *name = CGTypeToAttrName
+                               (info, (ILType *)(argValue->un.strValue.str));
+                       ILSerializeWriterSetString(writer, name, strlen(name));
+               }
+               break;
+
+               case IL_META_SERIALTYPE_VARIANT:
+               {
+                       /* Note : We assume the values are castable and
+                        * do not provide any checks here */
+                       if(ILType_IsPrimitive(argType))
+                       {
+                               switch(argValue->valueType)
+                               {       
+                                       case ILMachineType_Boolean:
+                                       case ILMachineType_Int8:
+                                       case ILMachineType_UInt8:
+                                       case ILMachineType_Int16:
+                                       case ILMachineType_UInt16:
+                                       case ILMachineType_Char:
+                                       case ILMachineType_Int32:
+                                       case ILMachineType_UInt32:
+                                       case ILMachineType_Int64:
+                                       case ILMachineType_UInt64:
+                                       case ILMachineType_Float32:
+                                       case ILMachineType_Float64:
+                                       case ILMachineType_Decimal:
+                                       {
+                                               
serialType=ILSerializeGetType(argType);
+                                               
+                                               
ILSerializeWriterSetBoxedPrefix(writer, 
+                                                                               
                                   serialType);
+
+                                               WriteSerializedEntry(info, 
writer, paramType, 
+                                                                               
         argValue, argType, serialType);
+                                       }
+                                       break;
+                                       
+                                       case ILMachineType_String:
+                                       {
+                                               /* TODO */
+                                       }
+                                       break;
+                                       
+                                       default:
+                                       {
+                                       }
+                                       break;
+                               }
+                       }
+                       else if(ILTypeIdentical(argType, systemType))
+                       { 
+                               ILSerializeWriterSetBoxedPrefix(writer,
+                                                                               
IL_META_SERIALTYPE_TYPE);
+                               
+                               WriteSerializedEntry(info, writer, paramType, 
+                                                                        
argValue, argType,
+                                                                        
IL_META_SERIALTYPE_TYPE);
+                       }
+                       else if(ILTypeIsEnum(argType))
+                       {
+                               const char *name = CGTypeToAttrName(info, 
(ILType *)(argType));
+                               ILSerializeWriterSetBoxedPrefix(writer,
+                                                                               
IL_META_SERIALTYPE_ENUM);
+                               ILSerializeWriterSetString(writer, name, 
strlen(name));
+
+                               serialType=ILSerializeGetType(argType);
+
+                               WriteSerializedEntry(info, writer, paramType,
+                                                                               
argValue, argType,
+                                                                               
serialType);    
+                       }
+               }
+               break;
+
+               default:
+               {
+                       if(ILType_IsArray(paramType))
+                       {
+                               /* TODO: arrays */
+                       }
+               }
+               break;
+       }
+}
+
+/*
+ * Write a custom attribute.
+ */
+static int WriteCustomAttribute(ILGenInfo *info,
+                                                               CGAttributeInfo 
*attributeInfo)
+{
+       int argNum;
+       int serialType;
+       ILType *signature;
+       ILType *paramType;
+       ILType *argType;
+       ILAttribute *attribute;
+       ILMethod *methodInfo;
+       ILEvalValue *argValue;
+       const void *blob;
+       unsigned long blobLen;
+       int haveErrors = 0;
+       ILSerializeWriter *writer = 0;
+
+       /* Import the constructor method into this image */
+       methodInfo = (ILMethod *)ILMemberImport(info->image,
+                                                                               
        (ILMember *)attributeInfo->ctor);
+       if(!methodInfo)
+       {
+               ILGenOutOfMemory(info);
+       }
+
+       /* Check if all types can be serialized */
+       signature = ILMethod_Signature(methodInfo);
+       for(argNum = 0; argNum < attributeInfo->numArgs; ++argNum)
+       {
+               if(attributeInfo->ctorArgs[argNum].evalValue.valueType != 
ILMachineType_Void)
+               {
+                       paramType = ILTypeGetParam(signature, argNum + 1);
+
+                       if(ILSerializeGetType(paramType) == -1)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->ctorArgs[argNum].node,
+                                                          _("attribute 
argument %d is not serializable"),
+                                                          argNum + 1);
+                               haveErrors = 1;
+                       }
+               }
+       }
+
+       for(argNum = 0; argNum < attributeInfo->numNamed; ++argNum)
+       {
+               if(attributeInfo->namedArgs[argNum].evalValue.valueType != 
ILMachineType_Void)
+               {
+                       paramType = attributeInfo->namedArgs[argNum].type;
+
+                       if(ILSerializeGetType(paramType) == -1)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[argNum].node,
+                                                         _("named attribute 
argument %d is not serializable"),
+                                                         argNum + 1);
+                               haveErrors = 1;
+                       }
+               }
+       }
+
+       if(haveErrors)
+       {
+               return 0;
+       }
+
+       /* Build the serialized attribute value */
+       writer = ILSerializeWriterInit();
+       if(!writer)
+       {
+               ILGenOutOfMemory(info);
+       }
+       for(argNum = 0; argNum < attributeInfo->numArgs; ++argNum)
+       {
+               paramType = ILTypeGetParam(signature, argNum + 1);
+               argValue = &(attributeInfo->ctorArgs[argNum].evalValue);
+               argType = attributeInfo->ctorArgs[argNum].type;
+               serialType = ILSerializeGetType(paramType);
+               WriteSerializedEntry(info, writer, paramType, argValue, argType,
+                                                        serialType);
+       }
+       ILSerializeWriterSetNumExtra(writer, attributeInfo->numNamed);
+       for(argNum = 0; argNum < attributeInfo->numNamed; ++argNum)
+       {
+               argValue = &(attributeInfo->namedArgs[argNum].evalValue);
+               if(argValue->valueType == ILMachineType_Void)
+               {
+                       serialType = IL_META_SERIALTYPE_TYPE;
+                       paramType = NULL;
+               }
+               else
+               {
+                       paramType = ILValueTypeToType(info, 
argValue->valueType);
+                       serialType = ILSerializeGetType(paramType);
+               }
+               if(ILMember_IsField(attributeInfo->namedArgs[argNum].member))
+               {
+                       ILSerializeWriterSetField
+                               (writer, 
ILMember_Name(attributeInfo->namedArgs[argNum].member),
+                                serialType);
+               }
+               else
+               {
+                       ILSerializeWriterSetProperty
+                               (writer, 
ILMember_Name(attributeInfo->namedArgs[argNum].member),
+                                serialType);
+               }
+               argType = attributeInfo->namedArgs[argNum].type;
+               WriteSerializedEntry(info, writer, paramType, argValue, argType,
+                                                        serialType);
+       }
+       blob = ILSerializeWriterGetBlob(writer, &blobLen);
+       if(!blob)
+       {
+               ILGenOutOfMemory(info);
+       }
+
+       /* Add the attribute value to the program item */
+       attribute = ILAttributeCreate(info->image, 0);
+       if(!attribute)
+       {
+               ILGenOutOfMemory(info);
+       }
+       ILAttributeSetType(attribute, ILToProgramItem(methodInfo));
+       if(!ILAttributeSetValue(attribute, blob, blobLen))
+       {
+               ILGenOutOfMemory(info);
+       }
+       ILProgramItemAddAttribute(attributeInfo->owner, attribute);
+
+       ILSerializeWriterDestroy(writer);
+
+       return 1;
+}
+
+/*
+ * Process a serializable attribute on a class, struct or enum.
+ */
+static int SerializableAttribute(ILGenInfo *info,
+                                                                
CGAttributeInfo *attributeInfo)
+{
+       ILClass *classInfo;
+
+       if((classInfo = ILProgramItemToClass(attributeInfo->owner)) != 0)
+       {
+               ILClassSetAttrs(classInfo, IL_META_TYPEDEF_SERIALIZABLE,
+                                                                  
IL_META_TYPEDEF_SERIALIZABLE);
+               return 1;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The serializable attribute can be used only on types"));
+       return 0;
+}
+
+/*
+ * Process a non serialized attribute on a field.
+ */
+static int NonSerializedAttribute(ILGenInfo *info,
+                                                                 
CGAttributeInfo *attributeInfo)
+{
+       ILField *field;
+
+       if((field = ILProgramItemToField(attributeInfo->owner)) != 0)
+       {
+               ILMemberSetAttrs((ILMember *)field, 
IL_META_FIELDDEF_NOT_SERIALIZED,
+                                                                               
        IL_META_FIELDDEF_NOT_SERIALIZED);
+               return 1;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The non serialize attribute can be used only on fields"));
+       return 0;
+}
+
+/*
+ * Process an "in" attribute on a parameter.
+ */
+static int InAttribute(ILGenInfo *info,
+                                          CGAttributeInfo *attributeInfo)
+{
+       ILParameter *param;
+
+       /* We must use this on a parameter */
+       if((param = ILProgramItemToParameter(attributeInfo->owner)) != 0)
+       {
+               ILParameterSetAttrs(param, IL_META_PARAMDEF_IN,
+                                                                  
IL_META_PARAMDEF_IN);
+               return 1;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The in attribute can be used only on parameters"));
+       return 0;
+}
+
+/*
+ * Process an "out" attribute on a parameter.
+ */
+static int OutAttribute(ILGenInfo *info,
+                                               CGAttributeInfo *attributeInfo)
+{
+       ILParameter *param;
+
+       /* We must use this on a parameter */
+       if((param = ILProgramItemToParameter(attributeInfo->owner)) != 0)
+       {
+               ILParameterSetAttrs(param, IL_META_PARAMDEF_OUT,
+                                                                  
IL_META_PARAMDEF_OUT);
+               return 1;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The out attribute can be used only on parameters"));
+       return 0;
+}
+
+/*
+ * Process an "optional" attribute on a parameter.
+ */
+static int OptionalAttribute(ILGenInfo *info,
+                                                        CGAttributeInfo 
*attributeInfo)
+{
+       ILParameter *param;
+
+       /* We must use this on a parameter */
+       if((param = ILProgramItemToParameter(attributeInfo->owner)) != 0)
+       {
+               ILParameterSetAttrs(param, IL_META_PARAMDEF_OPTIONAL,
+                                                                  
IL_META_PARAMDEF_OPTIONAL);
+               return 1;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The optional attribute can be used only on parameters"));
+       return 0;
+}
+
+/*
+ * Process a "comimport" attribute on a type.
+ */
+static int ComImportAttribute(ILGenInfo *info,
+                                                         CGAttributeInfo 
*attributeInfo)
+{
+       ILClass *classInfo;
+
+       /* We must use this on a type */
+       if((classInfo = ILProgramItemToClass(attributeInfo->owner)) != 0)
+       {
+               ILClassSetAttrs(classInfo, IL_META_TYPEDEF_IMPORT,
+                                                                  
IL_META_TYPEDEF_IMPORT);
+               return 1;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The com import attribute can be used only on types"));
+       return 0;
+}
+
+/*
+ * Process a "StructLayout" attribute on a type.
+ */
+static int StructLayoutAttribute(ILGenInfo *info,
+                                                                
CGAttributeInfo *attributeInfo)
+{
+       ILClass *classInfo;
+
+       /* We must use this on a type */
+       if((classInfo = ILProgramItemToClass(attributeInfo->owner)) != 0)
+       {
+               ILClassLayout *layout;
+               ILUInt32 attrMask = 0;
+               ILUInt32 attrs = 0;
+               ILInt32 sizeValue = 0;
+               ILInt32 packValue = 0;
+               int currentNamedArg;
+
+               if(attributeInfo->numArgs != 1)
+               {
+                       CGErrorForNode(info, attributeInfo->node,
+                               _("incorrect number of arguments for the struct 
layout attribute"));
+                       return 0;
+               }
+
+               /* Convert the kind value into a layout attribute value */
+               attrMask |= IL_META_TYPEDEF_LAYOUT_MASK;
+               switch(attributeInfo->ctorArgs[0].evalValue.un.i4Value)
+               {
+                       case 0:
+                       {
+                               attrs |= IL_META_TYPEDEF_LAYOUT_SEQUENTIAL;
+                       }
+                       break;
+
+                       case 2:
+                       {
+                               attrs |= IL_META_TYPEDEF_EXPLICIT_LAYOUT;
+                       }
+                       break;
+
+                       case 3:
+                       {
+                               attrs |= IL_META_TYPEDEF_AUTO_LAYOUT;
+                       }
+                       break;
+
+                       default:
+                       {
+                               CGErrorForNode(info, 
attributeInfo->ctorArgs[0].node,
+                                       _("invalid structure layout"));
+                       }
+                       break;
+               }
+
+               for(currentNamedArg = 0; currentNamedArg < 
attributeInfo->numNamed; ++currentNamedArg)
+               {
+                       ILField *field;
+                       ILProgramItem *item;
+                       const char *fieldName;
+
+                       item = 
ILToProgramItem(attributeInfo->namedArgs[currentNamedArg].member);
+                       if((field = ILProgramItemToField(item)) == 0)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("Invalid named field for the struct 
layout attribute"));
+                               continue;
+                       }
+                       fieldName = ILField_Name(field);
+                       if(!fieldName)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("Invalid named field for the struct 
layout attribute"));
+                               continue;
+                       }
+                       if(!strcmp(fieldName, "CharSet"))
+                       {
+                               attrMask |= IL_META_TYPEDEF_STRING_FORMAT_MASK;
+                               
switch(attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value)
+                               {
+                                       case 1:
+                                       case 2:
+                                       {
+                                               attrs |= 
IL_META_TYPEDEF_ANSI_CLASS;
+                                       }
+                                       break;
+
+                                       case 3:
+                                       {
+                                               attrs |= 
IL_META_TYPEDEF_UNICODE_CLASS;
+                                       }
+                                       break;
+
+                                       case 4:
+                                       {
+                                               attrs |= 
IL_META_TYPEDEF_AUTO_CLASS;
+                                       }
+                                       break;
+
+                                       default:
+                                       {
+                                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                                       _("Invalid CharSet 
specified for the struct layout attribute"));
+                                       }
+                                       break;
+                               }
+                       }
+                       else if(!strcmp(fieldName, "Size"))
+                       {
+                               sizeValue = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+                       }
+                       else if(!strcmp(fieldName, "Pack"))
+                       {
+                               packValue = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+                               switch(packValue)
+                               {
+                                       case 1:
+                                       case 2:
+                                       case 4:
+                                       case 8:
+                                       case 16:
+                                       case 32:
+                                       case 64:
+                                       case 128:
+                                       {
+                                               /* OK */
+                                       }
+                                       break;
+
+                                       default:
+                                       {
+                                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                                       _("Invalid Pack 
specified for the struct layout attribute"));
+                                       }
+                                       break;
+                               }
+                       }
+                       else
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("Invalid named field for the struct 
layout attribute"));
+                               return 0;
+                       }
+               }
+
+               /* Change the attributes for the class */
+               ILClassSetAttrs(classInfo, attrMask, attrs);
+
+               /* Add size and packing information if necessary */
+               layout = ILClassLayoutGetFromOwner(classInfo);
+               if(layout)
+               {
+                       /* Modify an existing layout information block */
+                       ILClassLayoutSetClassSize(layout, sizeValue);
+                       ILClassLayoutSetPackingSize(layout, packValue);
+               }
+               else
+               {
+                       /* Create a new layout block if necessary */
+                       if(sizeValue != 0 || packValue != 0)
+                       {
+                               
if(!ILClassLayoutCreate(ILProgramItem_Image(classInfo), 0,
+                                                                               
classInfo, packValue, sizeValue))
+                               {
+                                       ILGenOutOfMemory(info);
+                               }
+                       }
+               }
+
+               return 1;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The struct layout attribute can be used only on types"));
+       return 0;
+}
+
+/*
+ * Process a "FieldOffset" attribute on a field.
+ */
+static int FieldOffsetAttribute(ILGenInfo *info,
+                                                               CGAttributeInfo 
*attributeInfo)
+{
+       ILField *field;
+
+       if((field = ILProgramItemToField(attributeInfo->owner)) != 0)
+       {
+               if(attributeInfo->numArgs == 1)
+               {
+                       ILFieldLayout *layout;
+                       ILUInt32 offset;
+
+                       /* Set the field offset */
+                       offset = 
attributeInfo->ctorArgs[0].evalValue.un.i4Value;
+                       layout = ILFieldLayoutGetFromOwner(field);
+                       if(layout)
+                       {
+                               ILFieldLayoutSetOffset(layout, offset);
+                       }
+                       else if((layout = 
ILFieldLayoutCreate(ILProgramItem_Image(field), 0,
+                                                                               
                  field, offset)) == 0)
+                       {
+                               ILGenOutOfMemory(info);
+                       }
+                       return 1;
+               }
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of arguments for the field offset 
attribute"));
+               return 0;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The field offset attribute can be used only on fields"));
+       return 0;
+}
+
+/*
+ * Process a "DiiImport" attribute on a method (or field see notes).
+ */
+static int DllImportAttribute(ILGenInfo *info,
+                                                         CGAttributeInfo 
*attributeInfo)
+{
+       ILMethod *method = 0;
+       ILField *field = 0;
+       ILModule *module;
+       ILUInt32 attrMask = 0;
+       ILUInt32 attrs = 0;
+       const char *dllName = 0;
+       const char *entryPoint = 0;
+       int currentNamedArg;
+
+       if((method = ILProgramItemToMethod(attributeInfo->owner)) != 0)
+       {
+               /* Nothing to do here */
+       }
+       else if((field = ILProgramItemToField(attributeInfo->owner)) != 0)
+       {
+               if(!ILField_IsStatic(field) || ILField_IsLiteral(field))
+               {
+                       CGErrorForNode(info, attributeInfo->node,
+                               _("The dllimport attribute can be used only on 
static non constant fields"));
+                       return 0;
+               }
+       }
+       else
+       {
+               CGErrorForNode(info, attributeInfo->node,
+                       _("The dllimport attribute can be used only on methods 
and fields"));
+               return 0;
+       }
+
+       if(attributeInfo->numArgs != 1)
+       {
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of parameters passed to the 
constructor"));
+               return 0;
+       }
+       dllName = attributeInfo->ctorArgs[0].evalValue.un.strValue.str;
+       if(!dllName || attributeInfo->ctorArgs[0].evalValue.un.strValue.len <= 
0)
+       {
+               CGErrorForNode(info, attributeInfo->node,
+                       _("the name of the shared library must not be null or 
empty"));
+               return 0;
+       }
+
+       for(currentNamedArg = 0; currentNamedArg < attributeInfo->numNamed; 
++currentNamedArg)
+       {
+               ILProgramItem *item;
+               ILField *attrField;
+               const char *attrFieldName;
+
+               item = 
ILToProgramItem(attributeInfo->namedArgs[currentNamedArg].member);
+               if((attrField = ILProgramItemToField(item)) == 0)
+               {
+                       CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                               _("Invalid named field for the dllimport 
attribute"));
+                       continue;
+               }
+               attrFieldName = ILField_Name(attrField);
+               if(!attrFieldName)
+               {
+                       CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                               _("Invalid named field for the dllimport 
attribute"));
+                       continue;
+               }
+               if(!strcmp("CallingConvention", attrFieldName))
+               {
+                       ILUInt32 callConv;
+
+                       callConv = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+                       if(callConv < 1 || callConv > 5)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("Invalid calling convention specified 
for the dllimport attribute"));
+                               continue;
+                       }
+                       attrMask |= IL_META_PINVOKE_CALL_CONV_MASK;
+                       attrs |= (callConv << 8);
+               }
+               else if(!strcmp(attrFieldName, "CharSet"))
+               {
+                       ILUInt32 charSet;
+       
+                       attrMask |= IL_META_PINVOKE_CHAR_SET_MASK;
+                       charSet = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+                       switch(charSet)
+                       {
+                               case 1:
+                               {
+                                       /* None */
+                               }
+                               break;
+
+                               case 2:
+                               {
+                                       /* Ansi */
+                                       attrs |= IL_META_PINVOKE_CHAR_SET_ANSI;
+                               }
+                               break;
+
+                               case 3:
+                               {
+                                       /* Unicode */
+                                       attrs |= 
IL_META_PINVOKE_CHAR_SET_UNICODE;
+                               }
+                               break;
+
+                               case 4:
+                               {
+                                       /* Auto */
+                                       attrs |= IL_META_PINVOKE_CHAR_SET_AUTO;
+                               }
+                               break;
+
+                               default:
+                               {
+                                       CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                               _("Invalid character set 
specified for the dllimport attribute"));
+                                       continue;
+                               }
+                       }
+               }       
+               else if(!strcmp(attrFieldName, "EntryPoint"))
+               {
+                       entryPoint = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.strValue.str;
+
+                       if(!entryPoint ||
+                          
attributeInfo->namedArgs[currentNamedArg].evalValue.un.strValue.len <= 0)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("the entrypoint in of the shared 
library must not be null or empty"));
+                               return 0;
+                       }               
+               }
+               else if(!strcmp(attrFieldName, "ExactSpelling"))
+               {
+                       attrMask |= IL_META_PINVOKE_NO_MANGLE;
+
+                       
if(attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value)
+                       {
+                               attrs |= IL_META_PINVOKE_NO_MANGLE;
+                       }
+                       else
+                       {
+                               attrs &= ~IL_META_PINVOKE_NO_MANGLE;
+                       }
+               }
+               else if(!strcmp(attrFieldName, "PreserveSig"))
+               {
+                       attrMask |= IL_META_PINVOKE_OLE;
+
+                       
if(attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value)
+                       {
+                               attrs |= IL_META_PINVOKE_OLE;
+                       }
+                       else
+                       {
+                               attrs &= ~IL_META_PINVOKE_OLE;
+                       }
+               }
+               else if(!strcmp(attrFieldName, "SetLastError"))
+               {
+                       attrMask |= IL_META_PINVOKE_SUPPORTS_LAST_ERROR;
+
+                       
if(attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value)
+                       {
+                               attrs |= IL_META_PINVOKE_SUPPORTS_LAST_ERROR;
+                       }
+                       else
+                       {
+                               attrs &= ~IL_META_PINVOKE_SUPPORTS_LAST_ERROR;
+                       }
+               }
+               else
+               {
+                       CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                               _("Invalid named field for the dllimport 
attribute"));
+                       return 0;
+               }
+       }
+
+       module = 
ILModuleRefCreateUnique(ILProgramItem_Image(attributeInfo->owner), dllName);
+       if(!module)
+       {
+               ILGenOutOfMemory(info);
+       }
+       if(method)
+       {
+               if(!ILPInvokeCreate(method, 0, attrs, module, entryPoint))
+               {
+                       ILGenOutOfMemory(info);
+               }
+               /* Mark the method with the "pinvokeimpl" flag */
+               ILMemberSetAttrs((ILMember *)method,
+                                                IL_META_METHODDEF_PINVOKE_IMPL,
+                                                
IL_META_METHODDEF_PINVOKE_IMPL);
+       }
+       else
+       {
+               if(!ILPInvokeFieldCreate(field, 0, attrs, module, entryPoint))
+               {
+                       ILGenOutOfMemory(info);
+               }
+               /* Mark the field with the "pinvokeimpl" flag */
+               ILMemberSetAttrs((ILMember *)field,
+                                                IL_META_FIELDDEF_PINVOKE_IMPL,
+                                                IL_META_FIELDDEF_PINVOKE_IMPL);
+       }
+       return 1;
+}
+
+/*
+ * Add the marshalling information to the owner.
+ */
+static int AddMarshalling(ILGenInfo *info, ILProgramItem *owner,
+                                                 const unsigned char *blob, 
ILUInt32 blobLen)
+{
+       ILFieldMarshal *marshal;
+
+       marshal = ILFieldMarshalGetFromOwner(owner);
+       if(!marshal)
+       {
+               marshal = ILFieldMarshalCreate(ILProgramItem_Image(owner), 0, 
owner);
+               if(!marshal)
+               {
+                       ILGenOutOfMemory(info);
+                       return 0;
+               }
+       }
+       if(!ILFieldMarshalSetType(marshal, blob, blobLen))
+       {
+               ILGenOutOfMemory(info);
+               return 0;
+       }
+
+       return 1;
+}
+
+/*
+ * Process a marshal attribute on a field or parameter.
+ */
+static int MarshalAsAttribute(ILGenInfo *info,
+                                                         CGAttributeInfo 
*attributeInfo)
+{
+       ILField *field = 0;
+       ILParameter *param = 0;
+       ILUInt32 unmanagedType;
+       ILUInt32 arraySubType = IL_META_NATIVETYPE_MAX;
+       ILUInt32 safeArraySubType = IL_META_VARIANTTYPE_EMPTY;
+       const char *marshalCookie = 0;
+       int marshalCookieLen = 0;
+       int currentNamedArg;
+       ILInt32 sizeValue = 0;
+       ILInt32 sizeParamIndex = -1;
+       const char *marshalType = 0;
+       int marshalTypeLen = 0;
+
+       if((field = ILProgramItemToField(attributeInfo->owner)) != 0)
+       {
+               /* Nothing to do here */
+       }
+       else if((param = ILProgramItemToParameter(attributeInfo->owner)) != 0)
+       {
+               /* Nothing to do here */
+       }
+       else
+       {
+               CGErrorForNode(info, attributeInfo->node,
+                       _("The marshal as attribute can be used only on fields 
and parameters"));
+               return 0;
+       }
+
+       if(attributeInfo->numArgs != 1)
+       {
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of parameters passed to the 
constructor"));
+               return 0;
+       }
+
+       unmanagedType = attributeInfo->ctorArgs[0].evalValue.un.i4Value;
+       /* vaidate the unmanaged type */
+       switch(unmanagedType)
+       {
+               case 0x02:
+               case 0x03:
+               case 0x04:
+               case 0x05:
+               case 0x06:
+               case 0x07:
+               case 0x08:
+               case 0x09:
+               case 0x0A:
+               case 0x0B:
+               case 0x0C:
+               case 0x14:
+               case 0x15:
+               case 0x1F:
+               case 0x20:
+               case 0x26:
+               case 0x2A:
+               /* Non ECMA types */
+               case 0x0F:
+               case 0x13:
+               case 0x16:
+               case 0x17:
+               case 0x18:
+               case 0x19:
+               case 0x1A:
+               case 0x1B:
+               case 0x1C:
+               case 0x1D:
+               case 0x1E:
+               case 0x22:
+               case 0x23:
+               case 0x24:
+               case 0x25:
+               case 0x28:
+               case 0x2B:
+               case 0x2C:
+               case 0x2D:
+               {
+                       /* OK */
+               }
+               break;
+
+               default:
+               {
+                       CGErrorForNode(info, attributeInfo->ctorArgs[0].node,
+                               _("invalid unmanaged type passed to the 
constructor"));
+                       return 0;
+               }
+               break;
+       }
+
+       for(currentNamedArg = 0; currentNamedArg < attributeInfo->numNamed; 
++currentNamedArg)
+       {
+               ILProgramItem *item;
+               ILField *attrField;
+               const char *attrFieldName;
+
+               item = 
ILToProgramItem(attributeInfo->namedArgs[currentNamedArg].member);
+               if((attrField = ILProgramItemToField(item)) == 0)
+               {
+                       CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                               _("Invalid named field for the marshal as 
attribute"));
+                       continue;
+               }
+               attrFieldName = ILField_Name(attrField);
+               if(!attrFieldName)
+               {
+                       CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                               _("Invalid named field for the marshal as 
attribute"));
+                       continue;
+               }
+               if(!strcmp("ArraySubType", attrFieldName))
+               {
+                       arraySubType = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+               }
+               else if(!strcmp("SizeConst", attrFieldName))
+               {
+                       sizeValue = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+                       if(sizeValue < 0)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("The array size must be >= 0"));
+                       }
+               }
+               else if(!strcmp("SizeParamIndex", attrFieldName))
+               {
+                       if(!param)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("The size parameter index can only be 
set on marshal as attributes on parameters"));
+                       }
+                       else
+                       {
+                               sizeParamIndex = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+                               if(sizeParamIndex <= 0)
+                               {
+                                       CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                               _("The size parameter index 
must be >= 0"));
+                               }
+                       }
+               }
+               /* NON ECMA */
+               else if(!strcmp("SafeArraySubType", attrFieldName))
+               {
+                       safeArraySubType = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.i4Value;
+               }
+               else if(!strcmp("MarshalCookie", attrFieldName))
+               {
+                       marshalCookie = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.strValue.str;
+                       marshalCookieLen = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.strValue.len;
+                       if(!marshalCookie || marshalCookieLen <= 0)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("marshal cookie must not be null or 
empty"));
+                       }
+               }
+               else if(!strcmp("MarshalType", attrFieldName))
+               {
+                       marshalType = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.strValue.str;
+                       marshalTypeLen = 
attributeInfo->namedArgs[currentNamedArg].evalValue.un.strValue.len;
+                       if(!marshalType || marshalTypeLen <= 0)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("marshal type must not be null or 
empty"));
+                       }
+               }
+               else if(!strcmp("MarshalTypeRef", attrFieldName))
+               {
+                       ILType *type;
+
+                       type = (ILType 
*)attributeInfo->namedArgs[currentNamedArg].evalValue.un.oValue;
+                       marshalType = CGTypeToAttrName(info, type);
+                       if(!marshalType)
+                       {
+                               CGErrorForNode(info, 
attributeInfo->namedArgs[currentNamedArg].node,
+                                       _("invalid type"));
+                       }
+                       else
+                       {
+                               marshalTypeLen = strlen(marshalType);
+                       }
+               }
+       }
+
+       /* Build the marshalling blob that corresponds to the supplied data */
+       switch(unmanagedType)
+       {
+               case IL_META_NATIVETYPE_ARRAY:
+               {
+                       /* An array that has a size value in a separate 
parameter */
+                       unsigned char buf[64];
+                       int blobLen = 0;
+
+                       buf[0] = IL_META_NATIVETYPE_ARRAY;
+                       blobLen = 1 + ILMetaCompressData
+                               (buf + 1, (unsigned long)arraySubType);
+                       blobLen += ILMetaCompressData
+                               (buf + blobLen, (unsigned long)sizeParamIndex);
+                       buf[blobLen++] = 1;             /* Multiplier */
+                       blobLen += ILMetaCompressData
+                               (buf + blobLen, (unsigned long)sizeValue);
+
+                       if(!AddMarshalling(info, attributeInfo->owner, buf, 
blobLen))
+                       {
+                               return 0;
+                       }
+               }
+               break;
+
+               case IL_META_NATIVETYPE_SAFEARRAY:
+               {
+                       /* Safe variant array */
+                       unsigned char buf[64];
+                       int blobLen = 0;
+
+                       buf[0] = IL_META_NATIVETYPE_SAFEARRAY;
+                       blobLen = 1 + ILMetaCompressData
+                               (buf + 1, (unsigned long)safeArraySubType);
+
+                       if(!AddMarshalling(info, attributeInfo->owner, buf, 
blobLen))
+                       {
+                               return 0;
+                       }
+               }
+               break;
+
+               case IL_META_NATIVETYPE_FIXEDARRAY:
+               {
+                       /* Fixed length array */
+                       unsigned char buf[64];
+                       int blobLen = 0;
+
+                       buf[0] = IL_META_NATIVETYPE_FIXEDARRAY;
+                       blobLen = 1 + ILMetaCompressData
+                               (buf + 1, (unsigned long)sizeValue);
+                       blobLen += ILMetaCompressData
+                                       (buf + blobLen, (unsigned 
long)arraySubType);
+
+                       if(!AddMarshalling(info, attributeInfo->owner, buf, 
blobLen))
+                       {
+                               return 0;
+                       }
+               }
+               break;
+
+               case IL_META_NATIVETYPE_CUSTOMMARSHALER:
+               {
+                       /* Custom marshalling directive */
+                       unsigned char buf[IL_META_COMPRESS_MAX_SIZE * 2 +
+                                                         3 + marshalTypeLen + 
marshalCookieLen];
+                       int blobLen = 0;
+
+                       buf[0] = IL_META_NATIVETYPE_CUSTOMMARSHALER;
+                       buf[1] = 0;     /* Length of GUID string (unused) */
+                       buf[2] = 0;     /* Length of native type name string 
(unused) */
+                       blobLen = 3;
+                       blobLen += ILMetaCompressData
+                               (buf + blobLen, (unsigned long)marshalTypeLen);
+                       if(marshalTypeLen > 0)
+                       {
+                               ILMemCpy(buf + blobLen, marshalType, 
marshalTypeLen);
+                               blobLen += marshalTypeLen;
+                       }
+                       blobLen += ILMetaCompressData
+                               (buf + blobLen, (unsigned 
long)marshalCookieLen);
+                       if(marshalCookieLen > 0)
+                       {
+                               ILMemCpy(buf + blobLen, marshalCookie, 
marshalCookieLen);
+                               blobLen += marshalCookieLen;
+                       }
+
+                       if(!AddMarshalling(info, attributeInfo->owner, buf, 
blobLen))
+                       {
+                               return 0;
+                       }
+               }
+               break;
+
+
+               default:
+               {
+                       unsigned char buf[64];
+                       int blobLen = 0;
+
+                       /* This native type is represented as a simple value */
+                       blobLen = ILMetaCompressData(buf, (unsigned 
long)unmanagedType);
+
+                       if(!AddMarshalling(info, attributeInfo->owner, buf, 
blobLen))
+                       {
+                               return 0;
+                       }
+               }
+               break;
+       }
+
+       if(field)
+       {
+               ILMemberSetAttrs((ILMember *)field,
+                                                
IL_META_FIELDDEF_HAS_FIELD_MARSHAL,
+                                                
IL_META_FIELDDEF_HAS_FIELD_MARSHAL);
+       }
+       else if(param)
+       {
+               ILParameterSetAttrs(param,
+                                                       
IL_META_PARAMDEF_HAS_FIELD_MARSHAL,
+                                                       
IL_META_PARAMDEF_HAS_FIELD_MARSHAL);
+       }
+
+       return 1;
+}
+
+/*
+ * Process a default value attribute on a field, parameter or property.
+ */
+static int DefaultValueAttribute(ILGenInfo *info,
+                                                                
CGAttributeInfo *attributeInfo)
+{
+       ILField *field = 0;
+       ILParameter *param = 0;
+       ILProperty *property = 0;
+       ILType *type;
+       ILImage *image;
+       ILConstant *constant;
+       ILNativeUInt elementType;
+       unsigned char blob[8];
+       unsigned long blobLen;
+       
+       if((field = ILProgramItemToField(attributeInfo->owner)) != 0)
+       {
+               type = ILFieldGetType(field);
+       }
+       else if((param = ILProgramItemToParameter(attributeInfo->owner)) != 0)
+       {
+               ILNode_MethodDeclaration *methodNode;
+               ILUInt32 paramNum;
+               ILMethod *method;
+               ILType *signature;
+
+               paramNum = ILParameter_Num(param);
+               if(info->currentMethod && yyisa(info->currentMethod,
+                                                                               
ILNode_MethodDeclaration))
+               {
+                       methodNode = (ILNode_MethodDeclaration 
*)(info->currentMethod);
+               }
+               else
+               {
+                       return 0;
+               }
+               method = methodNode->methodInfo;
+               if(!method)
+               {
+                       return 0;
+               }
+               signature = ILMethod_Signature(method);
+               if(!signature)
+               {
+                       return 0;
+               }
+               type = ILTypeGetParam(signature, paramNum);
+       }
+       else if((property = ILProgramItemToProperty(attributeInfo->owner)) != 0)
+       {
+               ILMethod *method;
+               ILType *signature;
+
+               if((method = ILPropertyGetGetter(property)) != 0)
+               {
+                       /* The property type is the type of the return value */
+                       signature = ILMethod_Signature(method);
+                       if(!signature)
+                       {
+                               return 0;
+                       }
+                       type = ILTypeGetParam(signature, 0);
+               }
+               else if((method = ILPropertyGetSetter(property)) != 0)
+               {
+                       unsigned long numParams;
+
+                       /* The property type is the type of the last parameter 
*/
+                       signature = ILMethod_Signature(method);
+                       if(!signature)
+                       {
+                               return 0;
+                       }
+                       numParams = ILTypeNumParams(signature);
+                       type = ILTypeGetParam(signature, numParams);
+               }
+               else
+               {
+                       /* No getter or setter so something must be wrong */
+                       return 0;
+               }
+       }
+       else
+       {
+               /* The default value attribute can be applied to everything. */
+               /* So make a real custom attribute out of this one */
+               return WriteCustomAttribute(info, attributeInfo);
+       }
+       if(attributeInfo->numArgs != 1)
+       {
+               /* There are ctors with more than one parameter */
+               /* Only those with one can be handled here */
+               if(!WriteCustomAttribute(info, attributeInfo))
+               {
+                       return 0;
+               }
+               goto setOwnerFlags;
+       }
+       if(!type)
+       {
+               return 0;
+       }
+       if(!ILGenCastConst(info, &(attributeInfo->ctorArgs[0].evalValue),
+                                          
attributeInfo->ctorArgs[0].evalValue.valueType,
+                                          ILTypeToMachineType(type)) &&
+          !ILCanCastKind(info, attributeInfo->ctorArgs[0].type,
+                                         type, IL_CONVERT_STANDARD ,0))
+       {
+               CGErrorForNode(info, attributeInfo->ctorArgs[0].node,
+                                          _("could not coerce constant 
argument %d"), 1);
+               return 0;
+       }
+       type = ILTypeGetEnumType(type);
+       if(ILType_IsPrimitive(type))
+       {
+               elementType = ILType_ToElement(type);
+               switch(elementType)
+               {
+                       case IL_META_ELEMTYPE_BOOLEAN:
+                       {
+                               blob[0] = (unsigned 
char)(attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                               blobLen = 1;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_CHAR:
+                       {
+                               ILUInt16 value;
+
+                               value = 
(ILUInt16)(attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                               IL_WRITE_UINT16(blob, value);
+                               blobLen = 2;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_I1:
+                       case IL_META_ELEMTYPE_U1:
+                       {
+                               blob[0] = (unsigned 
char)(attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                               blobLen = 1;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_I2:
+                       {
+                               ILInt16 value;
+
+                               value = 
(ILInt16)(attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                               IL_WRITE_INT16(blob, value);
+                               blobLen = 2;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_U2:
+                       {
+                               ILUInt16 value;
+
+                               value = 
(ILUInt16)(attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                               IL_WRITE_UINT16(blob, value);
+                               blobLen = 2;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_I4:
+                       {
+                               ILInt32 value;
+
+                               value = 
(ILInt32)(attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                               IL_WRITE_INT32(blob, value);
+                               blobLen = 4;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_U4:
+                       {
+                               ILUInt32 value;
+
+                               value = 
(ILUInt32)(attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                               IL_WRITE_UINT32(blob, value);
+                               blobLen = 4;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_I8:
+                       {
+                               ILInt64 value;
+
+                               value = 
(ILInt64)(attributeInfo->ctorArgs[0].evalValue.un.i8Value);
+                               IL_WRITE_INT64(blob, value);
+                               blobLen = 8;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_U8:
+                       {
+                               ILUInt64 value;
+
+                               value = 
(ILUInt64)(attributeInfo->ctorArgs[0].evalValue.un.i8Value);
+                               IL_WRITE_UINT64(blob, value);
+                               blobLen = 8;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_R4:
+                       {
+                               ILFloat value;
+
+                               value = 
attributeInfo->ctorArgs[0].evalValue.un.r4Value;
+                               IL_WRITE_FLOAT(blob, value);
+                               blobLen = 4;
+                       }
+                       break;
+
+                       case IL_META_ELEMTYPE_R8:
+                       {
+                               ILDouble value;
+
+                               value = 
attributeInfo->ctorArgs[0].evalValue.un.r8Value;
+                               IL_WRITE_DOUBLE(blob, value);
+                               blobLen = 8;
+                       }
+                       break;
+
+                       default:
+                       {
+                               /* This type cannot be converted to a constant 
*/
+                               if(!WriteCustomAttribute(info, attributeInfo))
+                               {
+                                       return 0;
+                               }
+                               goto setOwnerFlags;
+                       }
+                       break;
+               }
+       }
+       else if(ILTypeIsStringClass(type))
+       {
+               if(attributeInfo->ctorArgs[0].evalValue.un.strValue.str == 0)
+               {
+                       elementType = IL_META_ELEMTYPE_CLASS;
+                       blob[0] = 0;
+                       blob[1] = 0;
+                       blob[2] = 0;
+                       blob[3] = 0;
+                       blobLen = 4;
+               }
+               else
+               {
+                       void *utf16;
+                       const char *str;
+
+                       elementType = IL_META_ELEMTYPE_STRING;
+                       str = 
attributeInfo->ctorArgs[0].evalValue.un.strValue.str;
+                       utf16 = StringToUTF16(str, &blobLen,
+                                                                 
attributeInfo->ctorArgs[0].evalValue.un.strValue.len);
+                       if(!utf16)
+                       {
+                               ILGenOutOfMemory(info);
+                       }
+                       image = ILProgramItem_Image(attributeInfo->owner);
+                       constant = ILConstantCreate(image, 0, 
attributeInfo->owner,
+                                                                               
IL_META_ELEMTYPE_STRING);
+                       if(!constant)
+                       {
+                               ILFree(utf16);
+                               ILGenOutOfMemory(info);
+                       }
+                       if(!ILConstantSetValue(constant, utf16, blobLen))
+                       {
+                               ILFree(utf16);
+                               ILGenOutOfMemory(info);
+                       }
+                       ILFree(utf16);
+                       goto setOwnerFlags;
+               }
+       }
+       else if(ILType_IsClass(type))
+       {
+               if(attributeInfo->ctorArgs[0].evalValue.un.oValue != 0)
+               {
+                       /* Non Null object references cannot be converted to a 
constant */
+                       return -1;
+               }
+               elementType = IL_META_ELEMTYPE_CLASS;
+               blob[0] = 0;
+               blob[1] = 0;
+               blob[2] = 0;
+               blob[3] = 0;
+               blobLen = 4;
+       }
+       else
+       {
+               /* This type cannot be converted to a constant */
+               return -1;
+       }
+
+       /* Create a constant node and attach it to the parameter */
+       image = ILProgramItem_Image(attributeInfo->owner);
+       constant = ILConstantCreate(image, 0, attributeInfo->owner,
+                                                               elementType);
+       if(!constant)
+       {
+               ILGenOutOfMemory(info);
+       }
+       if(!ILConstantSetValue(constant, blob, blobLen))
+       {
+               ILGenOutOfMemory(info);
+       }
+
+setOwnerFlags:
+       if(field)
+       {
+               ILMemberSetAttrs((ILMember *)field, 
IL_META_FIELDDEF_HAS_DEFAULT,
+                                                                               
        IL_META_FIELDDEF_HAS_DEFAULT);
+       }
+       else if(property)
+       {
+               ILMemberSetAttrs((ILMember *)property, 
IL_META_PROPDEF_HAS_DEFAULT,
+                                                                               
           IL_META_PROPDEF_HAS_DEFAULT);
+       }
+       else if(param)
+       {
+               ILParameterSetAttrs(param, IL_META_PARAMDEF_HAS_DEFAULT,
+                                                                  
IL_META_PARAMDEF_HAS_DEFAULT);
+       }
+       return 1;
+}
+
+/*
+ * Process a "MethodImpl" attribute on a method.
+ */
+static int MethodImplAttribute(ILGenInfo *info,
+                                                          CGAttributeInfo 
*attributeInfo)
+{
+       ILMethod *method;
+
+       /* We must use this on a method */
+       if((method = ILProgramItemToMethod(attributeInfo->owner)) != 0)
+       {
+               if(attributeInfo->numArgs == 1)
+               {
+                       ILMethodSetImplAttrs(method, 
~IL_META_METHODIMPL_CODE_TYPE_MASK,
+                               
(attributeInfo->ctorArgs[0].evalValue.un.i4Value &
+                                ~IL_META_METHODIMPL_CODE_TYPE_MASK));
+                       return 1;
+               }
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of arguments for the method impl 
attribute"));
+               return 0;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The method impl attribute can be used only on methods"));
+       return 0;
+}
+
+/*
+ * Process an "AssemblyAlgorithmId" attribute on an assembly.
+ */
+static int AssemblyAlgorithmIdAttribute(ILGenInfo *info,
+                                                                               
CGAttributeInfo *attributeInfo)
+{
+       ILAssembly *assembly;
+
+       /* We must use this on an assembly */
+       if((assembly = ILProgramItemToAssembly(attributeInfo->owner)) != 0)
+       {
+               if(attributeInfo->numArgs == 1)
+               {
+                       ILAssemblySetHashAlgorithm(assembly, 
(ILUInt32)attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                       return 1;
+               }
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of arguments for the assembly hash 
attribute"));
+               return 0;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The assembly hash attribute can be used only on 
assemblies"));
+       return 0;
+}
+
+/*
+ * Process an "AssemblyCulture" attribute on an assembly.
+ */
+static int AssemblyCultureAttribute(ILGenInfo *info,
+                                                                       
CGAttributeInfo *attributeInfo)
+{
+       ILAssembly *assembly;
+
+       /* We must use this on an assembly */
+       if((assembly = ILProgramItemToAssembly(attributeInfo->owner)) != 0)
+       {
+               if(attributeInfo->numArgs == 1)
+               {
+                       if(!ILAssemblySetLocale(assembly, 
attributeInfo->ctorArgs[0].evalValue.un.strValue.str))
+                       {
+                               ILGenOutOfMemory(info);
+                       }
+                       return 1;
+               }
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of arguments for the assembly 
culture attribute"));
+               return 0;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The assembly culture attribute can be used only on 
assemblies"));
+       return 0;
+}
+
+static int AssemblyFlagsAttribute(ILGenInfo *info,
+                                                                 
CGAttributeInfo *attributeInfo)
+{
+       ILAssembly *assembly;
+
+       /* We must use this on an assembly */
+       if((assembly = ILProgramItemToAssembly(attributeInfo->owner)) != 0)
+       {
+               if(attributeInfo->numArgs == 1)
+               {
+                       ILAssemblySetAttrs(assembly, 0, 
attributeInfo->ctorArgs[0].evalValue.un.i4Value);
+                       return 1;
+               }
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of arguments for the assembly flags 
attribute"));
+               return 0;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The assembly flags attribute can be used only on 
assemblies"));
+       return 0;
+}
+
+/*
+ * Parse an assembly version
+ */
+static int ParseVersion(ILGenInfo *info, const char *versionString, int len,
+                                               ILUInt16 *version, ILNode *attr)
+{
+       char currentChar;
+       int index;
+       int versionIndex;
+       ILUInt32 versionPart;
+
+       index = 0;
+       versionIndex = 0;
+       versionPart = 0;
+       while(index < len)
+       {
+               currentChar = versionString[index];
+               switch(currentChar)
+               {
+                       case '0':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                       case '8':
+                       case '9':
+                       {
+                               versionPart = versionPart * 10 + 
((ILUInt32)currentChar - '0');
+                               if(versionPart > 0xFFFF)
+                               {
+                                       /* Overflow */
+                                       CGErrorForNode(info, attr,
+                                                       _("an overflow occured 
in an assembly version part"));
+                                       return 0;
+                               }
+                       }
+                       break;
+
+                       case '.':
+                       {
+                               version[versionIndex] = (ILUInt16)versionPart;
+                               versionPart = 0;
+                               ++versionIndex;
+                               if(versionIndex > 3)
+                               {
+                                       /* To many parts in the version 
specifier */
+                                       CGErrorForNode(info, attr,
+                                                       _("version must consist 
of 4 parts only"));
+                                       return 0;
+                               }
+                       }
+                       break;
+
+                       case '*':
+                       {
+                               if(versionString[index + 1] != '\0')
+                               {
+                                       /* Asterix must be the last part in the 
version string */
+                                       return 0;
+                               }
+                               if(index > 0 && versionString[index - 1] != '.')
+                               {
+                                       /* Asterix must follow immediate a 
period */
+                                       CGErrorForNode(info, attr,
+                                                       _("the asterix must 
immediately follow after a period"));
+                                       return 0;
+                               }
+                               /* So fill the rest of the version with some 
random values */
+                               while(versionIndex < 4)
+                               {
+                                       version[versionIndex] = 0;
+                                       ++versionIndex;
+                               }
+                               return 1;
+                       }
+                       break;
+
+                       default:
+                       {
+                               /* Invalid character */
+                               CGErrorForNode(info, attr,
+                                               _("invalid character in the 
assebbly version"));
+                               return 0;
+                       }
+                       break;
+               }
+               ++index;
+       }
+       /* Handle the last part of the version */
+       if(versionIndex == 3)
+       {               
+               version[versionIndex] = (ILUInt16)versionPart;
+               return 1;
+       }
+       CGErrorForNode(info, attr, _("version must consist of 4 parts"));
+       return 0;
+}
+
+static int AssemblyVersionAttribute(ILGenInfo *info,
+                                                                       
CGAttributeInfo *attributeInfo)
+{
+       ILAssembly *assembly;
+
+       /* We must use this on an assembly */
+       if((assembly = ILProgramItemToAssembly(attributeInfo->owner)) != 0)
+       {
+               if(attributeInfo->numArgs == 1)
+               {
+                       ILUInt16 version[4];
+
+                       if(ParseVersion(info,
+                                                       
attributeInfo->ctorArgs[0].evalValue.un.strValue.str,
+                                                       
attributeInfo->ctorArgs[0].evalValue.un.strValue.len,
+                                                       version, 
attributeInfo->ctorArgs[0].node))
+                       {
+                               ILAssemblySetVersion(assembly, version);
+                               return 1;
+                       }
+                       return 0;
+               }
+               CGErrorForNode(info, attributeInfo->node,
+                       _("incorrect number of arguments for the assembly 
version attribute"));
+               return 0;
+       }
+       CGErrorForNode(info, attributeInfo->node,
+               _("The assembly version attribute can be used only on 
assemblies"));
+       return 0;
+}
+
+static CGAttrConvertInfo const systemAttrs[] = {
+       {"SerializableAttribute", SerializableAttribute},
+       {"NonSerializedAttribute", NonSerializedAttribute},
+       {0, 0}
+};
+static CGAttrConvertInfo const interopAttrs[] = {
+       {"InAttribute", InAttribute},
+       {"OutAttribute", OutAttribute},
+       {"OptionalAttribute", OptionalAttribute},
+       {"ComImportAttribute", ComImportAttribute},
+       {"StructLayoutAttribute", StructLayoutAttribute},
+       {"FieldOffsetAttribute", FieldOffsetAttribute},
+       {"DllImportAttribute",  DllImportAttribute},
+       {"MarshalAsAttribute", MarshalAsAttribute},
+       {0, 0}
+};
+static CGAttrConvertInfo const reflectionAttrs[] = {
+       {"AssemblyAlgorithmIdAttribute", AssemblyAlgorithmIdAttribute},
+       {"AssemblyCultureAttribute", AssemblyCultureAttribute},
+       {"AssemblyFlagsAttribute", AssemblyFlagsAttribute},
+       {"AssemblyVersionAttribute", AssemblyVersionAttribute},
+       {0, 0}
+};
+static CGAttrConvertInfo const compilerAttrs[] = {
+       {"MethodImplAttribute", MethodImplAttribute},
+       {0, 0}
+};
+static CGAttrConvertInfo const componentModelAttrs[] = {
+       {"DefaultValueAttribute", DefaultValueAttribute},
+       {0, 0}
+};
+
+/*
+ * Handle a pseudo custom attribute that is stored in the metadata directly.
+ * Returns     1 if the attribute was handled successfully.
+ *                     0 if it's not a pseudo custom attribute.
+ *                     -1 if there was an error in the pseudo custom attribute.
+ */
+static int HandlePseudoCustomAttribute(ILGenInfo *info,
+                                                                          
CGAttributeInfo *attributeInfo)
+{
+       ILClass *attrClass;
+       const char *namespace;
+       const char *name;
+       const CGAttrConvertInfo *convertInfo = 0;
+
+       attrClass = ILMember_Owner(attributeInfo->ctor);
+       if(!attrClass)
+       {
+               return 0;
+       }
+       namespace = ILClass_Namespace(attrClass);
+       name = ILClass_Name(attrClass);
+
+       if(namespace)
+       {
+               if(!strcmp(namespace, "System.Runtime.InteropServices"))
+               {
+                       convertInfo = interopAttrs;
+               }
+               else if(!strcmp(namespace, "System.Runtime.CompilerServices"))
+               {
+                       convertInfo = compilerAttrs;
+               }
+               else if(!strcmp(namespace, "System.Reflection"))
+               {
+                       convertInfo = reflectionAttrs;
+               }
+               else if(!strcmp(namespace, "System"))
+               {
+                       convertInfo = systemAttrs;
+               }
+               else if(!strcmp(namespace, "System.ComponentModel"))
+               {
+                       convertInfo = componentModelAttrs;
+               }
+       }
+       if(convertInfo)
+       {
+               while(convertInfo->name != 0 && strcmp(convertInfo->name, name) 
!= 0)
+               {
+                       ++convertInfo;
+               }
+               if(convertInfo)
+               {
+                       if(convertInfo->func)
+                       {
+                               int result;
+
+                               result = (*(convertInfo->func))(info, 
attributeInfo);
+                               if(result > 0)
+                               {
+                                       return 1;
+                               }
+                               else if(result == 0)
+                               {
+                                       return -1;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+/*
+ * Determine if a class is "AttributeUsageAttribute".
+ */
+static int IsAttributeUsage(ILClass *classInfo)
+{
+       const char *namespace;
+
+       if(strcmp(ILClass_Name(classInfo), "AttributeUsageAttribute") != 0)
+       {
+               return 0;
+       }
+       namespace = ILClass_Namespace(classInfo);
+       if(!namespace || strcmp(namespace, "System") != 0)
+       {
+               return 0;
+       }
+       if(ILClass_NestedParent(classInfo) != 0)
+       {
+               return 0;
+       }
+       return 1;
+}
+
+/*
+ * Determine if a class is "ConditionalAttribute".
+ */
+static int IsConditionalAttribute(ILClass *classInfo)
+{
+       const char *namespace;
+
+       if(strcmp(ILClass_Name(classInfo), "ConditionalAttribute") != 0)
+       {
+               return 0;
+       }
+       namespace = ILClass_Namespace(classInfo);
+       if(!namespace || strcmp(namespace, "System.Diagnostics") != 0)
+       {
+               return 0;
+       }
+       if(ILClass_NestedParent(classInfo) != 0)
+       {
+               return 0;
+       }
+       return 1;
+}
+
+/*
+ * Check if the attribute target is valid.
+ */
+static int AttributeTargetIsValid(ILGenInfo *info, ILProgramItem *owner,
+                                                                 ILClass 
*attribute,
+                                                                 
ILAttributeUsageAttribute *attributeUsage,
+                                                                 ILNode *node,
+                                                                 ILUInt32 
target)
+{
+       if(IsAttributeUsage(attribute))
+       {
+               ILClass *classInfo;
+               /* We can only use "AttributeUsageAttribute" on classes
+                  that inherit from "System.Attribute" */
+               classInfo = ILProgramItemToClass(owner);
+               if(!classInfo ||
+                  !ILTypeAssignCompatible(info->image, 
ILClassToType(classInfo),
+                                                                  
ILFindSystemType(info, "Attribute")))
+               {
+                       CGErrorForNode(info, node,
+                       _("`System.AttributeUsageAttribute' is allowed only on 
attributes"));
+                       return 0;
+               }
+       }
+       else if(IsConditionalAttribute(attribute))
+       {
+               if(target == IL_ATTRIBUTE_TARGET_CLASS)
+               {
+                       ILClass *classInfo;
+
+                       classInfo = ILProgramItemToClass(owner);
+                       if(!classInfo ||
+                          !ILTypeAssignCompatible(info->image, 
ILClassToType(classInfo),
+                                                                          
ILFindSystemType(info, "Attribute")))
+                       {
+                               CGErrorForNode(info, node,
+                                           _("The attribute `%s' is not 
allowed on `%s'"),
+                                               CGClassToName(attribute),
+                                               AttributeTargetToName(target));
+                               return 0;
+                       }
+               }
+               else if(target != IL_ATTRIBUTE_TARGET_METHOD)
+               {
+                       CGErrorForNode(info, node,
+                                                  _("The attribute `%s' is not 
allowed on `%s'"),
+                                                  CGClassToName(attribute),
+                                                  
AttributeTargetToName(target));
+                       return 0;
+               }
+       }
+       else
+       {
+               ILUInt32 validOn;
+
+               validOn = ILAttributeUsageAttributeGetValidOn(attributeUsage);
+               if((validOn & target) == 0)
+               {
+                       CGErrorForNode(info, node,
+                                                  _("The attribute `%s' is not 
allowed on `%s'"),
+                                                  CGClassToName(attribute),
+                                                  
AttributeTargetToName(target));
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+/*
+ * Add an attribute to the attribute infos.
+ */
+int CGAttributeInfosAddAttribute(CGAttributeInfos *attributeInfos,
+                                                                ILNode *node,
+                                                                ILProgramItem 
*owner,
+                                                                ILMethod *ctor,
+                                                                CGAttrCtorArg 
*ctorArgs,
+                                                                ILUInt32 
numArgs,
+                                                                CGAttrNamedArg 
*namedArgs,
+                                                                ILUInt32 
numNamed,
+                                                                ILUInt32 
target)
+{
+       CGAttributeInfo *attributeInfo;
+       ILClass *attribute;
+       ILAttributeUsageAttribute *attributeUsage;
+       ILBool allowMultiple;
+
+       if(attributeInfos == 0)
+       {
+               return 0;
+       }
+       if(ctor == 0)
+       {
+               return 0;
+       }
+       attribute = ILMethod_Owner(ctor);
+       /* Get the usage information for the attribute */
+       attributeUsage = ILClassGetAttributeUsage(attribute);
+       if(!attributeUsage)
+       {
+               CGErrorForNode(attributeInfos->info, node,
+                                          _("Failed to retrieve AttibuteUsage 
information"));
+               return 0;
+       }
+       /* Check if the attribute is valid for this target */
+       if(!AttributeTargetIsValid(attributeInfos->info, owner, attribute,
+                                                          attributeUsage, 
node, target))
+       {
+               return 1;
+       }
+       allowMultiple = 
ILAttributeUsageAttributeGetAllowMultiple(attributeUsage);
+
+       attributeInfo = ILMemStackAlloc(&(attributeInfos->memstack),
+                                                                       
CGAttributeInfo);
+       if(attributeInfo == 0)
+       {
+               ILGenOutOfMemory(attributeInfos->info);
+       }
+       attributeInfo->node = node;
+       attributeInfo->owner = owner;
+       attributeInfo->ctor = ctor;
+       attributeInfo->ctorArgs = ctorArgs;
+       attributeInfo->numArgs = numArgs;
+       attributeInfo->namedArgs = namedArgs;
+       attributeInfo->numNamed = numNamed;
+       attributeInfo->next = attributeInfos->attributes;
+       attributeInfos->attributes = attributeInfo;
+
+       return 1;
+}
+
+/*
+ * Process the attributes.
+ */
+int CGAttributeInfosProcess(CGAttributeInfos *attributeInfos)
+{
+       CGAttributeInfo *attributeInfo;
+
+       if(attributeInfos == 0)
+       {
+               return 0;
+       }
+
+       attributeInfo = attributeInfos->attributes;
+       while(attributeInfo)
+       {
+               /* Handle pseudo custom attributes stored in the metadata 
directly */
+               if(!HandlePseudoCustomAttribute(attributeInfos->info, 
attributeInfo))
+               {
+                       WriteCustomAttribute(attributeInfos->info, 
attributeInfo);
+               }
+
+               attributeInfo = attributeInfo->next;
+       }
+       return 1;
+}
+
+#ifdef __cplusplus
+};
+#endif

Index: codegen/cg_genattr.h
===================================================================
RCS file: codegen/cg_genattr.h
diff -N codegen/cg_genattr.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ codegen/cg_genattr.h        19 Apr 2009 11:43:43 -0000      1.1
@@ -0,0 +1,130 @@
+/*
+ * cg_genattrs.h - handle custom attributes.
+ *
+ * Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef        __CODEGEN_CG_GENATTR_H__
+#define        __CODEGEN_CG_GENATTR_H__
+
+#include "cg_nodes.h"
+#include "il_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Structure to hold constructor arguments.
+ */
+typedef struct _tagCGAttrCtorArg  CGAttrCtorArg;
+struct _tagCGAttrCtorArg
+{
+       ILType             *type;                       /* type of the ctor 
argument */
+       ILNode             *node;                       /* only for error 
output */
+       ILNode            **parent;                     /* not used, only for 
convinience */
+       ILEvalValue             evalValue;              /* constant value 
passed to the ctor */
+};
+
+typedef struct _tagCGAttrNamedArg  CGAttrNamedArg;
+struct _tagCGAttrNamedArg
+{
+       ILType             *type;                       /* type stored in item 
*/
+       ILNode             *node;                       /* only for error 
output */
+       ILNode            **parent;                     /* not used, only for 
convinience */
+       ILMember           *member;                     /* field or property */
+       ILEvalValue             evalValue;              /* constant value 
passed to the named argument */
+};
+
+typedef struct _tagCGAttributeInfo CGAttributeInfo;
+struct _tagCGAttributeInfo
+{
+       ILNode             *node;                       /* only for error 
output */
+       ILProgramItem  *owner;
+       ILMethod           *ctor;
+       CGAttrCtorArg  *ctorArgs;
+       CGAttrNamedArg *namedArgs;
+       ILUInt32                numArgs;
+       ILUInt32                numNamed;
+       CGAttributeInfo *next;
+               
+};
+
+/*
+ * Block to hold the information for the custom attributes
+ * to be emitted for a program item.
+ */
+typedef struct _tagCGAttributeInfos  CGAttributeInfos;
+struct _tagCGAttributeInfos
+{
+       ILMemStack              memstack;
+       ILGenInfo          *info;
+       CGAttributeInfo *attributes;
+               
+};
+
+/*
+ * Initialize an attribute info block,
+ */
+void CGAttributeInfosInit(ILGenInfo *info,
+                                                 CGAttributeInfos 
*attributeInfos);
+
+/*
+ * Destroy an attribute info block,
+ */
+void CGAttributeInfosDestroy(CGAttributeInfos *attributeInfos);
+
+/*
+ * Allocate numArgs CGAttrCtorArgs.
+ * Returns 0 if numArgs is 0 or attributeInfos is 0.
+ */
+CGAttrCtorArg *CGAttrCtorArgAlloc(CGAttributeInfos *attributeInfos,
+                                                                 ILUInt32 
numArgs);
+
+/*
+ * Allocate numNamed CGAttrNamedArgs.
+ * Returns 0 if numNamed is 0 or attributeInfos is 0.
+ */
+CGAttrNamedArg *CGAttrNamedArgAlloc(CGAttributeInfos *attributeInfos,
+                                                                       
ILUInt32 numNamed);
+
+/*
+ * Add an attribute to the attribute infos.
+ * Returns 0 if any argumant is not valid and 1 on success.
+ * Success is even if the attribute is not added because of a target error.
+ */
+int CGAttributeInfosAddAttribute(CGAttributeInfos *attributeInfos,
+                                                                ILNode *node,
+                                                                ILProgramItem 
*owner,
+                                                                ILMethod *ctor,
+                                                                CGAttrCtorArg 
*ctorArgs,
+                                                                ILUInt32 
numArgs,
+                                                                CGAttrNamedArg 
*namedArgs,
+                                                                ILUInt32 
numNamed,
+                                                                ILUInt32 
target);
+
+/*
+ * Process the collected attributes.
+ */
+int CGAttributeInfosProcess(CGAttributeInfos *attributeInfos);
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* __CODEGEN_CG_GENATTR_H__ */

Index: codegen/cg_intl.h
===================================================================
RCS file: codegen/cg_intl.h
diff -N codegen/cg_intl.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ codegen/cg_intl.h   19 Apr 2009 11:43:43 -0000      1.1
@@ -0,0 +1,53 @@
+/*
+ * cg_intl.h - Internationalization support for "cscc" and its plugins.
+ *
+ * Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef        _CODEGEN_CG_INTL_H
+#define        _CODEGEN_CG_INTL_H
+
+#include "il_values.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if HAVE_LIBINTL_H && HAVE_GETTEXT
+
+#include <libintl.h>
+#define        _(str)  (gettext((str)))
+#ifdef gettext_noop
+       #define N_(str) (gettext_noop((str)))
+#else
+       #define N_(str) (str)
+#endif
+
+#else
+
+#define        _(str)  (str)
+#define        N_(str) (str)
+#define        textdomain(domain)
+#define        bindtextdomain(package,directory)
+
+#endif
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* _CODEGEN_CG_INTL_H */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]